If you are making a web application which needs to update client in realtime, you can use this example to quickly write such an application in nodejs using socket.io.Redis pubsub is used as a data source in this example. You can use any other data source. Angular LiveSet is the preferred way to create to create real-time apps for LoopBack. For an introduction, see Build Real-Time Node.js Apps with Angular LiveSet and LoopBack. This tutorial describes how you can build a LoopBack server with the capability to “push” live updates to connected AngularJS clients. Installing Socket.io.
This article was peer reviewed by Craig Bilner and Dan Prince. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
An important part of writing rich internet applications is reacting to data changes. Consider the following quote by Guillermo Rauch, taken from his 2014 BrazilJS talk, The 7 Principles of Rich Web Applications.
When data changes on the server, let the clients know without asking. This is a form of performance improvement that frees the user from manual refresh actions (F5, pull to refresh). New challenges: (re)connection management, state reconciliation.
In this article we’ll look at examples of how to use the raw WebSocket API as well as the lesser known EventSource for server-sent events (SSE) to build “real-time” UI’s that are self-updating. If you’re unsure what I mean by that, I recommend watching the video referenced above, or reading the corresponding blog post.
A Brief History
In the past we had to simulate server-push, the most notable method being long polling. This involved the client making a long request that would remain open until the server was ready to push a message. After receiving a message the request would be closed and a new request would be made. Other solutions involved
<iframe>
hacks and Flash. This was not ideal.Then, in 2006, Opera introduced server-sent events (SSE) from the WHATWG Web Applications 1.0 specification.
SSE allowed you to stream events continuously from your web server to the visitor’s browser. Other browsers followed suit and started implementing SSE in 2011 as part of the HTML5 spec.
SSE allowed you to stream events continuously from your web server to the visitor’s browser. Other browsers followed suit and started implementing SSE in 2011 as part of the HTML5 spec.
Things continued to get interesting in 2011 when the WebSocket protocol was standardised. WebSockets allow you to open a two-way persistent connection between client and server, giving you the ability to push data back to the clients whenever data changes on the server without the client having to request it. This is hugely important for the responsiveness of an application with a lot of concurrent connections and quickly changing content—a multiplayer online game for example. However, it wasn’t until socket.io—the most prominent effort to bring WebSockets to the masses—was released in 2014 that we saw a lot more experimentation happening with real time communication.
Suffice to say, that today we have much simpler ways of achieving server-push without issuing new requests or relying on non-standard plugins. These technologies give you the ability to stream data back to the client the moment things happen on the server.
WebSockets
The easiest way to understand what a persistent connection allows you to do is to run a working demo, we’ll step through the code later but for now download the demo and have a play.
Demo
Open http://localhost:8080/ in multiple browser windows and observe the logs in both the browser and the server to see messages going back and forth. More importantly note the time it takes to receive a message on the server and for the rest of the connected clients to be made aware of the change.
The Client
The
WebSocket
constructor initiates a connection with the server over the ws
or wss
(Secure) protocols. It has a send
method for pushing data to the server and you can provide an onmessage
handler for receiving data from the server.Here’s an annotated example showing all of the important events:
The Server
By far, the most popular Node library for working with WebSockets on the server is ws, we’ll use that to simplify things as writing WebSocket servers is not a trivial task.
The
ws
package makes building a WebSocket enabled server simple, you should read up on WebSocket Security if you’re using them in production though.Browser Compatibility
Browser support for WebSockets is solid, the exceptions being Opera Mini and IE9 and below, there’s a polyfill available for older IE’s which uses Flash behind the scenes.
Can I Use WebSockets? Data on support for the websockets feature across the major browsers from caniuse.com.
Debugging
In Chrome you can inspect messages sent and received under Network > WS > Frames, sent messages show up in green.
WebSocket debugging in Firefox is possible using the Websocket Monitor addon for the Firefox Dev Tools. It is developed by the Firebug development team.
Server-Sent Events
Like WebSockets, SSE opens a persistent connection that allows you to send data back to the connected clients the second something is changed on the server. The only caveat is that it doesn’t allow messages to go the other direction. That’s not really a problem though, we still have good old fashioned Ajax techniques for that.
Demo
As before, open http://localhost:8080/ in multiple browser windows and observe the logs in both the browser and the server to see messages going back and forth.
The Client
The
EventSource
function initiates a connection with the server over good old HTTP or HTTPS. It has a similar API to WebSocket
and you can provide an onmessage
handler for receiving data from the server. Here’s an annotated example showing all of the important events.The Server
There’s a neat little wrapper sse for creating server-sent events. We’ll use that to simplify things at first but sending events from the serveris simple enough to do ourselves so we’ll explain how SSE on the server works later.
Sending Events from the Server
As mentioned above, sending events from the server is simple enough to do ourselves. Here’s how:
When a HTTP request comes in from
EventSource
it will have an Accept
header of text/event-stream
, we need to respond with headers that keep the HTTP connection alive, then when we are ready to send data back to the client we write data to the Response
object in a special format data: <data>nn
.In addition to the
data
field you can also send event, id and retry fields if you need them e.g.Although SSE is wonderfully simple to implement on both the client and the server, as mentioned above, its one caveat is that it doesn’t provide a way to send data from the client to the server. Luckily, we can already do that with
XMLHttpRequest
or fetch
. Our new found superpower is to be able to push from the server to the client.For security, as it’s HTTP the standard Cross-Origin rules apply so you should always whitelist origins on both the server and the client:
Then we can still push to the server as usual with good old Ajax:
Browser Compatibility
Browser support for SSE is lower than WebSocket due to Microsoft never having shipped a browser that supports it, there is a bug report for it and you should all vote for SSE to help make it a priority for the next release.
Can I Use WebSockets? Data on support for the websockets feature across the major browsers from caniuse.com.
If you need to get SSE working in IE and Edge today you can use a Polyfill for EventSource.
Debugging
In Chrome you can inspect messages received under Network > XHR > EventStream
Challenges
In Guillermo Rauch’s article quoted at the beginning (re)connection management and state reconciliation are mentioned as new challenges that these persistent connections have introduced. He’s right, you need to think about what should occur when the connection is lost and when it is re-connected.
EventSource
has a built-in re-connection mechanism, it will attempt to reconnect every 3 seconds if a connection is lost automatically. You can test this out in the SSE demo by making a connection in the browser and stopping the server with Ctrl + C, you’ll see errors being logged until you start the server back up again with npm start
, it keeps calm and carries on.WebSocket
doesn’t have this ability, if a connection is lost you’ll need to create a new one and wire up the events again if you want that same behaviour.State reconciliation is the practice of synchronising the client with the server when a re-connection occurs. One way to do this is to keep track of the time that a disconnection happened and upon re-connection send all of the events that particular client had missed out on whilst disconnected.
The solutions to these challenges vary depending on what type of app you’re building:
- If you’re building a multiplayer online game you may need to halt the game until reconnection happens.
- In a Single Page App you may want to start saving changes locally and then send bulk updates to the server on reconnection.
- If you have a traditional app with only a couple of “real-time” pages you may not care if a connection is lost as things will be eventually consistent.
Frameworks
It’s fair to say that the era of WebSockets is upon us. No matter what programming language you run on the server there will be a framework that includes methods for handling persistent connections and broadcasting to connected clients.
On the client-side these frameworks give you methods for addressing the challenges of (re)connection management and state reconciliation and give you a simple way to subscribe to different “channels”. On the server-side they offer you the pooling of open connections and give you broadcast mechanisms.
When implementing a real-time feature in your app, there’s no need to throw away what you know about HTTP and start again. You can get started by adding one additional route (or channel) which clients can subscribe to, something that would benefit from being updated in real-time. Treat it as a performance improvement for both the client and server, the client is instantly updated the moment something happens and the server doesn’t need to respond to the tedious polling:
Are we there yet? Are we there yet?
Now, the server can respond at the start.
I’ll tell you when we’re there
Links
Are you using WebSockets or server-sent events in production? Is there a framework I’ve missed that deserves a mention? Be sure to let me know in the comments.
Active6 years, 2 months ago
I have a PHP application where people post different status messages. I want to implement realtime notifications in it.
That is if a user posts something, immediately other users accessing the site will get a prompt on their screen about a new post. I have heard you can use node.js to implement it. But I don't know how exactly it can be done. Any help will kindly be appreciated.
Morgan16.4k55 gold badges4747 silver badges7373 bronze badges
SanksSanks
closed as off-topic by andrewsi, NT3RP, QuinnG, Jonathan Potter, Karl AndersonJul 26 '13 at 21:16
This question appears to be off-topic. The users who voted to close gave this specific reason:
- 'Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist' – andrewsi, NT3RP, Jonathan Potter, Karl Anderson
2 Answers
I suggest you to take a look at socket.io. Client send a message to node, node can save to db (or forward with a RESTful call to your php application) and notify all clients.
It's not php but only nodejs and js. Enjoy ;)
Example
SERVER:
CLIENT
You have to write what you want to be done in the client in
Daniele Brugnaraon('yourEvent', function() { ...
Daniele Brugnara
2,13211 gold badge1717 silver badges3131 bronze badges
You can use Long Polling technique.
Long polling
is the name used to describe a technique which:- An AJAX request is made (utilizing a javascript framework such as jQuery)
- The server waits for the data requested to be available, loops, and sleeps (your server-side PHP script)
- This loop repeats after data is returned to the client and processed (usually in your AJAX request's onComplete callback function)
or
Try a server side pushing tech like Commet.
KonsoleKonsole3,18822 gold badges2222 silver badges3838 bronze badges