WebSockets + React: Should I use a single connection for multiple functions? - reactjs

I added a WebSocket API through AWS API Gateway on my React app.
I originally added it to build a chat messaging section, however, I soon realized how useful it could be for other things in the app that might need real-time updates.
I had an idea, and that is to store the socket in a React context so it's accessible from all the components of the app and that should work fine, without re-establishing a connection every time a component mounts.
Now, the question is, is there a better way to do what I'm trying to do? Hence, create a socket connection that I can then take advantage of for multiple functions? Say for instance, "is online" status.
The alternative is to create yet another socket API but is that really necessary?
Keep in mind I'm using a serverless framework (API) with lambda functions on AWS.

This is going to depend on the applications planned scale, keeping in mind that as the app usage grows you may want to refine the endpoint architecture and code.
Remember that an auth endpoint/api for example may only need to be accessed a few times over a chat interaction endpoint/api. For scalability (and cost per endpoint call too) id be looking at keeping them separate.

Related

Script Hosting (API to Database)

I am currently creating a react native + expo application upon which essentially each page makes an API call, which is a lot of API calls. I have this app also connected to firebase for different information. The things is, each of these pages don't update more than once or twice a day for the most part, so I really don't want the End User to be calling the API that much either.
My question is, is there a way to write and host a script that will continuously run that knows to call this API once every hour (or so) and then rewrite to the firebase db from which I can then only need to pull from the database as compared to having each user individually making dozens of API calls.
Please let me know! I have spent days on google and am no closer than I was before. I'm also willing to change my set up from firebase if it is not possible to accomplish that way. Thanks!
You can use a Cloud Functions scheduled trigger to run code periodically that can make changes to your database.

Chat app: What to do on successful re-connection to the WebSocket server?

My friend and I are currently building a web-based chat app with WebSocket. I'm in charge of client side (React + Redux). Golang is used for the server side (I don't know whether this is a good combination, but I do this just for fun).
Basically my problem is that I don't know what to do after the successful re-connection to the WebSocket server.
More concretely:
The client side tries to reconnect to the server when the connection is lost. My questions are
When the re-connection is successful, what should I do with the data that were supposed to be sent to the server, but actually weren't sent because of the lost connection? Is it better to have something like a buffer to store all the data that are not yet transmitted to the server?
Currently, a React component do the initial fetch of all the necessary data ( rooms, friends, chat history, etc.) on componentDidMount. For the app to be in sync with the server on successful re-connection, the app should perform actions similar to the initial fetch. But calling componentDidMount deliberately does not seem to be a good idea, because it is not supposed to be called in this way. Is it good to perform initial fetching in componentDidMount in the first place?
Since this is is a general question, I will answer in general terms:
You need some kind of buffer between the application and the unreliable stream. Since you're reactive, you can implement this using an observable. The service that is responsible for the actual communication over WebSocket will subscribe to this feed.
Separate the initialization of the component from initialization of the data. If you're communicating over WebSocket, you can reinitialize data every time the socket connects.
Go is certainly a good choice for the chat server because of the way it handles concurrency. The other common option for chat servers is Erlang. React is a matter of personal preference.
You probably don't want to buffer it all. You just want to buffer the messages but not, for instance, typing indicators because they make no sense if not sent immediately. Something as simple as an array with push() and shift() would do.
Move data fetching to a separate function, then call it both from componentDidMount and from the callback or whatever place where you reconnect.
Using both HTTP and websocket in one app is a matter of design. It does seem to complicate things though.

Securing a single page application built on react/react-router

I've been putting together a single-page application using React and React-Router and I can't seem to understand how these applications can be secured.
I found a nice clear blog post which shows one approach, but it doesn't look very secure to me. Basically, the approach presented in that post is to restrict rendering of components which the user is not authorized to access. The author wrote a couple more posts which are variations on the idea, extending it to React-Router routes and other components, but at their hearts all these approaches seem to rely on the same flawed idea: the client-side code decides what to do based on data in the store at the time the components are composed. And that seems like a problem to me - what's to stop an enterprising hacker from messing around with the code to get access to stuff?
I've thought of three different approaches, none of which I'm very happy with:
I could certainly write my authorization code in such a way that the client-side code is constantly checking with the server for authorization, but that seems wasteful.
I could set the application up so that modules are pushed to the client from the server only after the server has verified that the client has authority to access that code. But that seems to involve breaking my code up into a million little modules instead of a nice, monolithic bundle (I'm using browserify).
Some system of server-side rendering might work, which would ensure that the user could only see pages for which the server has decided they have authority to see. But that seems complicated and also seems like a step backward (I could just write a traditional web app if I wanted the server to do everything).
So, what is the best approach? How have other people solved this problem?
If you’re trying to protect the code itself, it seems that any approach that either sends that code to the client, or sends the code able to load that code, would be a problem. Therefore even traditional simple approaches with code splitting might be problematic here, as they reveal the filename for the bundle. You could protect it by requiring a cookie on the server, but this seems like a lot of fuss.
If hiding the internal code from unauthorized users is a requirement for your application, I would recommend splitting it into two separate apps with separate bundles. Going from one to another would require a separate request but this seems to be consistent with what you want to accomplish.
Great question. I'm not aware of any absolute best practices floating around out there that seem to outstrip others, so I'll just provide a few tips/thoughts here:
a remote API should handle the actual auth, of course.
sessions need to be shared, so a store like redis is usually a good idea, esp. for fast reads.
if you're doing server-side rendering that involves hydration, you'll need a way to share the session state between server and client. See the link below for one way to do universal react
on the client, you could send down a session cookie or JWT token, read it into memory (maybe using redux and keep it in your state tree?) and maybe use middleware (a la redux?) to set it as a header on requests.
on the client, you could also rely on localStorage to save the cookie/JWT
maybe split the code into two bundles, one for auth, one for the actual app logic?
See also:
https://github.com/erikras/react-redux-universal-hot-example for hydration example
https://github.com/erikras/react-redux-universal-hot-example/issues/608
As long as the store does not contain data that the user is not authorized to have, there shouldn't be too much of a problem even if a hacker checks the source and sees modules/links that he shouldn't have access to.
The state inside the store as well as critical logic would come from services and those need to be secured, whether it's an SPA or not; but especially on an SPA.
Also: server-side rendering with Redux isn't too complex. You can read about it here:
http://redux.js.org/docs/recipes/ServerRendering.html
It's basically only used to serve a root html with a predefined state. This further increases security and loading speeds but does not defy the idea behind SPAs.

How to tie signalR to IoC

I am writing web app in angular, using Nancy as my backend. I have setup signalR websockets as my primary communication mechanism. It works great, with one exception. I can't figure out how to attach state to my socket connection and make it easily available to my code. To be more specific, I can create and maintain state, I am finding it difficult to make that state available to everything on the back end that needs it, without passing a state data object around through every call.
I was hoping to tie to Nancy's IoC, but that is based off of the session, not off of a websocket. I looked at other IoC systems, but I cannot grok how to tie them to the socket.
Does anyone have any insight on how to maintain state non-obtrusively with signalR?
EDIT: This may explain it. When the user connects via signalR, I want to create an IGame instance with a life cycle that is tied to the signalR session and inject it throughout my code as needed. for that particular user.
Is that any clearer?

Laravel: Making a Real Time Application using Angular

I am starting to work with angular and am fascinated by the bi-directional data-binding capabilities and by its $http method, which lets me save changes in to my mysql database, without refreshing the page.
Another thing I am currently fascinated by is the real time capability across multiple clients using firebase. Here all clients are updated in REAL TIME, when the database receives any changes. I'd probably like to use firebase, but I would have to drop Laravel and MySql as a persistence layer entirely, which I would like to keep for the moment, since my application is already working in Laravel, just not in real time.
How would I go about having a Real Time application, which updates every client, without refreshing the view, in Laravel using MySQL and Angular?
If I am not mistaken, Pusher and PubNub, are providing this necessary open connection with the server using websockets, so when the server has something to share, angular will now and render it.
Since I would like to use Laravel and MySQL as a persistence layer, I am not sure, what the best way would be. I am not even sure, if I understood everything correctly, which I wrote above, since I am new to angular and real-time applications.
What would be the next necessary steps, to get some Real-Time capability into a PHP/MySQL application?
The solution for your problem is:
1º - open websocket connection with the websocket-server and subscribe a channel, after this send the data to your serve using ajax
tutorial angular pusher
2º - In server side, you get the data, saves to your database and send a 'PUBLISH' to the respective channel into websocket server
lib useful for this
3º - Through the subscribe gets the data in real time
Pusher.subscribe('channel', 'event', function (item) {
// code
});
I had a similar problem recently and I finally ended up using Redis publish/subscribe Redis. You can store data in the channel and then subscribe to any changes. When something changes you can send it to Pusher which will send it then to the clients.
I also recommend considering Node.js and Socket.io since you can achieve very good performance without third party service, and even if you don't have experience with node you can find very good examples on Socket.IO how to write an application.
For Redis there is a good library for PHP called Predis and there is Redis Node client as well, so you can mix it all together.

Resources