keep socket open in node + express - node.js

I am making a webapplication with multiple pages using nodejs, express & socket.io. One of the features is push notifications. This means socket.io should be running on every page. Connecting to socket.io on every page load takes a lot of time, which slows down the app.
Is there a way to keep the connection to the socket open?
One way would be to use ajax to render different pages inside my root page, but I think this will over complicate the app.
Is there a better way to implement this?

Are you sure you're handling the client side the right way ?
If you have a single page application, the browser should almost never reload completely the page. You should be using some client-side framework to handle SPA mechanisms (routing, templating, etc) like angularjs/backbone/ember/etc...
With a well formated SPA you load your app only once and it is kept alive without page reload as long as the browser tab is opened. So you weboscket would be created also only once. You shouldn't have any problem of this kind, your server side code is OK, it's just that you're doing it wrong client-side.
By the way, if you want to do handle only push data, you should take a look at the Server Sent Events, which is simplier/lighter that a full-duplex implementation like socket.io (which is a bit heavy)

Related

Update HTML page on mongodb data change

I want to update the HTML/pug page of multiple users when particular data changes in my MongoDB database. A user(A) follows another user(B) (whose data is stored in a different collection). When user(B) updates something, user(A) should see the change. There can be multiple people following the same user, and all the people following the user should see live updates.
I tried looking into socket.io but it doesn't look like it is the right thing for my purpose.
Your main options are either websockets (socket.io), server side push notifications with http2, or polling with http.
If socket.io seems overkill, server push notifications probably will too.
You can poll instead. Ie, send an http request from the client at regular intervals, like every 10 (or whatever seems suitable) seconds and update the page based on the response data
You’ll need to use JavaScript on the client for this. Pug templates render just once on page load. If you want dynamic updates after the initial render, you need client side JavaScript in all cases.

What is the purpose of React Router?

Given that we can do routing with Express on the server, why do need a client side router?
What are the benefits, and is it only significant to SPA?
Client side routing is required to keep your application in sync with the browser URL.
It is mainly useful for Single Page Applications where the backend will be used for RESTful API calls via XHR or AJAX calls.
Being a SPA uses can book mark your URL and when they hit the URL again , your application should load that page with the data and its state.
The main difference between Server side routing and client side routing:
1. In Server Side routing you download(serve) the entire page.
2. In client Side routing along with the entire page, you can serve a specific portion of a page, reuse the DOM, manually manage the URL and history states. eg.
www.something.com/page1/tab1 will show tab1 in the UI
www.something.com/page1.tab2 will show tab2 in the UI
In this way the url can get more complex and you can have sub-routes with states.
Those who need a client-side router, need it for state management. Say you have server-rendered pages, but with some client-side widgets - e.g. a calendar, set of filters or collapsed or open sidebar. Router helps you initialize these components of the page in the exact state you want them. Granted, you could do most of it and all of the use cases I've named on the server, too. But it's usually a lot easier to handle these on the client. You might render it faster on the server, but sometimes, especially when doing partial page updates, it's cheaper and faster to handle that client-side.

Node.js send variable to client

I have a small Node.js HTTP server that does requests to a mongo database (with the mongoose module).
What I want to do is query the database, store it in a variable (array) and send it to the client.
Because ideally, when the user clicks on one of the buttons on the html page, the JavaScript will pick-up the event and change the appearance of the website by showing calculations based on data that is stored in the database.
The only way I could come with was just "transferring" the database content to the client browser but if anyone can come with another solution that would be fine too !
So basically my question is :
How can I pass a variable from the Node.js server to the client browser when serving a page ?
Thank you in advance !
If you will be doing more than a couple of these types of transfers, I recommend looking into Socket.IO.
It's a layer that provides quick and easy communication between Node.js servers and web front-ends, by abstracting web sockets when available, and falling back to other transports (such as JSON-P or Flash) when it's not available. Basically, you would call io.emit('something', {yourdata: here}), and it is easily received on the other end. All of the serialization is done for you.
http://socket.io/
Give their demo a shot to see how it works.

Detecting an html button click with node.js?

I'm quite new to node.js, so my apologies if this is a potentially stupid question. I'm aware that when a new page is requested, it triggers a data event, which node can then handle accordingly; on my current project though, I have an html button that triggers a few events, but does not redirect the page. Because of this, node isn't recognizing that this is occurring. Is there any way for me to detect this? Or even, as a workaround, is there any way to call one of my node functions from the javascript embedded in the web page?
Thanks~
you are mixing up two different things, the data event in node which you are talking of is triggered because a network connection is established when you point the browser to your website, data is received and sent from the client to the server and back.
this has nothing to do with clientside ui events, for example a click event on a button.
if you want node to recognize a click on your button you have to send something to the server, you can either use a form, issue an ajax request or use websockets.
for ajax requests with jquery : jquery $.ajax documentation
a popular websockets implementation for node.js is socket.io
If you want to call something in Node from the client side, you can use socket.io to transfer events to Node. Then catch those events, and return the correct data back to the client. Refer to the socket.io "How to Use".

Node.js+Socket.io: Templating # server or browser? Load content via ajax or socket.io?

I already asked a similar question but this one is a bit different/specific:
I'm about to start development of a social community site (for a local user group) with features like timeline, IM/chat, forums, ...
Node.js and socket.io (or now.js) on the backend. jQuery (and maybe backbone.js or similar) on the front end. Content is loaded via socket.io or ajax and navigation via url hash.
There are 2 things where I just can't decide which way to go. I hope here are some people who can provide some good or bad experience.
Templating on server or in browser? I'm not sure if it's better to load a complete html site + live updates (also in html) for timeline, forum posts, IM/chat, ... or use something like a REST api via ajax or socket.io and do the templating on the client site. I've never done that before. You need to download the templates, etc, etc. Has anyone experience in this? There are also 2 ways to implement a rest-like api: E.g. request a forum post, then request the user associated to that post and so on (just like server side MVC) - or - request a forum post and the server answers with all needed information.
Load content via ajax or socket.io? I'm definitively using socket.io or now.js for real-time communication (IM, chat) and pubsub (on mainpage -> subscribe to new timeline updates, on a forum topic -> subscribe to new posts). But should I also load HTML (or provide a REST-like API, see question 1) through the socket? When people open forum posts in tabs (which I usually do a lot) that would mean a lot of socket connections. And I'm not sure how long it takes for a websocket to establish connection.
So there a 4 ways to do this:
HTML via AJAX - probably the most stable way that doesn't need a lot javascript to do the templating - Browser can use open HTTP connections to request stuff.
HTML via socket.io - The websocket must be established to load content (may be slower)
API via AJAX - as it probably needs more requests as HTML via AJAX there might be some HTTP header overhead + you need to authentication in each request- I'm not a friend of too many ajax requests.
API via socket.io - Socket must only be authenticated only once and you can request API objects on the fly. However I would still load templates and js via HTTP for browser caching.
I know this is a huge post but I'm debating for many days now and just can't decide as it would be a lot of work to switch the system once started developing. This is not a public project, it's limited to ~10k-15k local people and thus must not be that perfect, a good opportunity to learn new things in my opinion (I'm completely new to node, classic PHP MVC + jquery dev here).
I think you should use a RESTful api on the backend, let the templating occur just on the frontend (maybe with Backbone) and only use Socket.IO for real realtime stuff (such as chat). It doesn't make any sense to use websockets for something like loading HTML, because it most likely never changes.
So my vote is:
1) HTML via AJAX
2) API via AJAX
3) Realtime communication, such as chat messaging (or other stuff that constantly changes) via Socket.IO
Though there really isn't a definitive answer, as it depends.
If you need to be search engine crawlable, you can NOT rely only on client-side processing. If your individual views are light, and/or you need to support mobile, you should have initial rendering server-side.
Currently, I would suggest using an API that both your client application and server-side can use. If you use node for the server-side rendering you can re-use a lot of the same logic, including the API client.
Going a few steps farther, if you look starting with the Yahoo flux examples project on github, you can use the same logic both client and server-side including rendering with React views. This is not an easy solution, and will take some work.
For interactive elements, server-side rendering can be minimal with your stores pushing an event wiring up via sockjs/socket.io when the client starts for your chat/im bits.
You will have scalability issues when it comes to running across multiple processes and will likely need a pub/sub chain backed by a db for longer re-connect cycles or missed IM messages. There isn't a magic bullet.
Right now, I like flux+react... When Angular2 comes out, it may have a better story for server-side rendering.

Resources