Related
I have run into trouble with Socket.io regarding memory leaks and scaling issues lately. My decision to use Socket.io was made over a year ago when it was undoubtedly the best library to use.
Now that Socket.io causes much trouble, I spent time looking for alternatives that became available in the meantime and think that both Engine.io and SockJS are generally well suited for me. However, in my opinion both have some disadvantages and I am not sure which one to choose.
Engine.io is basically the perfect lightweight version of Socket.io that does not contain all the features I do not require anyway. I have already written my own reconnection and heartbeat logic for Socket.io, because I was not satisfied with the default logics and I never intended to use rooms or other features that Socket.io offers.
But - in my opinion - the major disadvantage of Engine.io is the way connections are established. Clients start with slower jsonp-polling and are upgraded if they support better transports. The fact that the clients which support websockets natively (number increasing steadily) have a disadvantage in the form of a longer and unstable connection procedure over those clients which use outdated browsers, contradicts my sense of how it should be handled.
SockJS on the other hand handles the connections exactly as I would like to. From what I have read it seems to be pretty stable while Engine.io has some issues at this time.
My app is running behind an Nginx router on a single domain, therefore I do not need the cross-domain functionality SockJS offers. Because of providing this functionality, however, SockJS does not expose the cookie data of the client at all. So far I had a 2-factor authorization with Socket.io via cookie AND query string token and this would not be possible with SockJS (with Engine.io it would).
I have read pretty much all what is avilable about and pros and cons of both, but it seems there is not much being discussed or published so far, espacially about Engine.io (there are only 8 questions tagged with engine.io here).
Which of the 2 libraries do you prefer and for which reason? Do you use them in production?
Which one will likely be maintained more actively and could have a major advantage over the other in the future?
Have you looked at Primus? It offers the cookie requirements you mention, it supports all of the major 'real-time'/websocket libraries available and is a pretty active project. To me it also sounds like vendor lock-in could be a concern for you and Primus would address that.
The fact that it uses a plugin system should also a) make it easier for you to extend if needed and b) may actually have a community plugin that already does what you need.
Which of the 2 libraries do you prefer and for which reason? Do you use them in production?
I have only used SockJS via the Vert.x API and it was for an internal project that I would consider 'production', but not a production facing consumer app. That said, it performed very well.
Which one will likely be maintained more actively and could have a major advantage over the other in the future?
Just looking over the commit history of Engine.io and SockJS, and the fact that Auttomatic is supporting Engine.io makes me inclined to think that it will be more stable, for a longer period of time, but of course that's debatable. Looking at the issues for Engine.io and SockJS is another good place to evaluate, but since they're both split over multiple repos it should be taken with a grain of salt. I'm not sure where/how Automattic is using Engine/Socket.io, but if it's in WordPress.com or one of their plugins, it has substantial production-at-scale battle testing.
edit: change answer to reflect cookie support confirmed by Primus author in comments below
I'd like to redirect you to this (quite detailed) discussion thread about SockJS and Engine.io
https://groups.google.com/forum/#!topic/sockjs/WSIdcY14ciI
Basically,
SockJS detects working transports before marking the connection
as open. Engine.io will immediately open the connection and upgrade
it later.
flash, one of the Engine.io fallbacks
(and not present in SockJS) loads slowly and in environments
behind proxies takes 3 seconds to timeout.
SockJS doesn't use flash and therefore doesn't need to work around
this issue.
SockJS does the upgrade on start. After that you have
a consistent experience. You send what you send, you receive
what you receive.
Also, as far as I can tell, engine.io-client (the client-side) library for engine.io, does not support requirejs builds, so that's another negative point. (SockJS does build perfectly).
You may also consider node-walve. Complete WebSocket basic. Extremely performant as fully stream based.
Example of how to use:
walve.createServer(function(wsocket) {
wsocket.on('incoming', function(incoming) {
incoming.pipe(process.stdout, { end: false });
});
}).listen(server);
It may not be the best choice if you feel not secure in the nodejs environment (e.g. extending prototypes for API sugar), contributing to the project (though the code is more readable as socket.io).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
or do Server-Sent Events and WebSocket replace Comet techniques?
I will approach this answer from both a terminology and historical perspective.
As I wrote in this other answer, we can use one of the several umbrella terms to refer to the set of technologies available to asynchronously send events from a web server to a web client (and vice versa). The "Push Technology" term has been used for fifteen years (for a short history of Push Technology you can see this old white paper I wrote many years ago—full disclosure: I am the creator of Lightstreamer). Now, the "Web Streaming" term is gaining consensus among the IT analysts (see Gartner, "Cool Vendors in Application and Integration Platforms, 2012", by Massimo Pezzini and Jess Thompson, 11 April 2012).
The important aspect is that we are talking about Web-based communication, that is, leveraging Web protocols. There are tons of messaging protocols and technologies that are not Web based (most of MOMs, for example) and we do not consider them as part of Push Technology (or Web Streaming).
That being said, you can distinguish between two sub-categories of Push Technology (or Web Streaming):
HTTP based
WebSockets based
Both HTTP and WebSockets are Web protocols.
If you explode the HTTP-based push mechanisms, you can identify:
HTTP Streaming
HTTP Long Polling
HTTP Polling
Traditionally, the "Comet" term (coined in 2006 by Alex Russell) has been referring to both HTTP Streaming and HTTP Polling. But consider that the first implementations of HTTP Streaming go back to 2000, well before the Comet term was coined (examples are Pushlets and Lightstreamer).
Now WebSockets make it simpler to implement Web Streaming, especially for the "backward" channel (messages sent from the browser to the server). For a more detailed explanation on the peculiarities of the backward channel over HTTP, see the final part of this article I wrote for CometDaily: http://cometdaily.com/2011/07/06/push-technology-comet-and-websockets-10-years-of-history-from-lightstreamers-perspective/
As pointed out by Phil, Comet is still necessary and will probably be for some more years, as there are not only old browsers around (including IE9, which does not support WebSockets…) but also infinite pieces of network intermediaries that do not speak WS. For example, we have seen that some mobile carriers in some countries (for example Vodafone Italy) support WSS but block WS. So a world without the Comet "hacks" is still far away… And let me add, on a personal note, that I've never loved the term "hack" applied to Comet (or, from a more correct historical point of view, applied to HTTP Streaming and HTTP Long Polling). Having worked on these techniques for 12 years now, I can say we have been able to refine them so much that they have become a full-blown technology themselves, completely reliable and used every day in many critical production scenarios (in finance, aerospace, and military, to name a few industries).
Now, let's imagine a world where WebSockets are universally supported and Comet is no more necessary. What do you get exactly? Well, just a bi-directional transport, nothing more... On the top of it you need to build everything: a messaging protocol (perhaps based on pub/sub), a server-side interface to talk to your server code, and a good set of optimization techniques and algorithms to manage the data flow, including bandwidth management, data conflation, automatic throttling, delta delivery, etc.
The good thing is that both the messaging protocols and the optimization mechanisms have already been implemented by good Comet solutions. So, extending former Comet servers to support WebSocket is the natural evolution that all of us vendors have implemented.
So, in a nutshell, in a not-so-near future WebSockets might make Comet transports obsolete, but will need to suck in all the higher layers already implemented and well tested on traditional Comet servers.
Comet is a set of technology principles/communication patterns that are typically implemented using HTTP long-poll. It enables a server to send data to the browser on demand (i.e. server push). Current comet implementations require some complex Javascript on the client side and support from the server-side (for long-held requests).
Server-Sent Events is a standard (HTML5) browser API for enabling this sort of on demand server push. You can think of Server-Sent Events as taking what has been done with complex Javascript and pushing it down into the browser itself.
WebSockets allows a browser to establish a persistent full-duplex/bi-directional connection to a server with WebSocket support. It does not require the client to keep making periodic HTTP requests to the server in order to maintain the connection as with AJAX/long-poll. Once the connection is established the overhead per message is very low (a few bytes) compared to the overhead with normal HTTP/HTTP long-poll. You can use WebSockets for efficient server push, but this is just one application.
There are also libraries that build on the AJAX/comet/WebSockets transport layer to provide things like session management, channels, broadcast, pubsub, etc. CometD is an example of this. Another popular example is Socket.IO. Both support WebSockets if it is available for the underlying transport but also support standard AJAX/long-poll if WebSockets is not available.
I initially thought that WebSockets realise Comet. They’re not an alternative. However, after some discussion I was later corrected and convinced by Alex Russell, the creator of "Comet", that this was not the case.
Comet, as #kanaka says, is a set of principles for simulating bi-directional communication between client and server (server push is half of the solution and is now provided by Server-Sent Events and the Event Source API).
However, Comet solutions are hacks because they work inconsistently across web browsers. For that reason Alex Russell says:
Next, are Web Sockets a form of Comet? Or is Comet just the HTTP hacks? I'm gonna go for the latter definition. The phrase and the hacks should probably ride off into the sunset together. I, for one, welcome our non-HTTP realtime overlords. To the extent that we can forget about old browsers (and god know I'm doing my bit: http://google.com/chromeframe), we can all get on board with "Web Sockets" and the need for any particular umbrella goes away.
So lets focus on that: how do we get users into a shiny new browser car? What sort of offer can we make to them about the richness and real-time experiences that an app based on WebSockets can deliver? Comet is about the past. Lets make the future real.
I'm now with Alex on this one. However, Comet - HTTP solutions - aren't going to become obsolete until:
Browser support is 100% and we don't need fallbacks for < IE10. I don't believe that Firefox, Safari, and Opera users are going to be a problem. There may be a small percentage of users that ignore the auto-update prompts for browsers like Firefox but not many.
Anti-virus manufacturers (such as Avast!) start support HTML5 web technologies and stop their software interfering with connectivity.
Some Internet infrastructure is updated to ensure the support of WebSockets. In my experiences connected over WSS over port 443 (a secure WebSocket connection) normally means connections make their way through Firewalls and Proxies but we want WS over port 80 to always be supported too.
While WebSocket does provide at the most fundamental level a way to communicate bi-directionally between a client and a server within the context of the Web and HTTP, it is a simple form of communications.
Comet provides more functionality on top of WebSocket (in fact, cometd even supports websocket), for features:
like publish/subscribe and channels of communications
fallback to older client<->server communications techniques when websocket is unvailable
I've been using WebSockets for a while now, I have chosen to create an Agile project management tool for my final year project at University utilizing Node server and WebSockets. I found using WebSockets provided a 624% increase in the number of requests per second my application could process.
However since starting the project I've read of security loopholes, and some browsers choosing to disable WebSockets by default..
This leads me to the question:
Why use AJAX when WebSockets seems to do such a great job of lowering latency and resource overhead, is there anything that AJAX does better than WebSockets?
WebSockets isn't intended to replace AJAX and is not strictly even a replacement for Comet/long-poll (although there are many cases where this makes sense).
The purpose of WebSockets is to provide a low-latency, bi-directional, full-duplex and long-running connection between a browser and server. WebSockets opens up new application domains to browser applications that were not really possible using HTTP and AJAX (interactive games, dynamic media streams, bridging to existing network protocols, etc).
However, there is certainly an overlap in purpose between WebSockets and AJAX/Comet. For example, when the browser wants to be notified of server events (i.e. push) then Comet techniques and WebSockets are certainly both viable options. If your application needs low-latency push events then this would be a factor in favor of WebSockets. On the other hand, if you need to co-exist with existing frameworks and deployed technologies (OAuth, RESTful APIs, proxies, load balancers) then this would be a factor in favor of Comet techniques (for now).
If you don't need the specific benefits that WebSockets provides, then it's probably a better idea to stick with existing techniques like AJAX and Comet because this allows you to re-use and integrate with a huge existing ecosystem of tools, technologies, security mechanisms, knowledge bases (i.e. far more people on stackoverflow know HTTP/Ajax/Comet than WebSockets), etc.
On the other hand, if you are creating a new application that just doesn't work well within the latency and connection constraints of HTTP/Ajax/Comet, then consider using WebSockets.
Also, some answers indicate that one of the downsides of WebSockets is limited/mixed server and browser support. Let me just diffuse that a bit. While iOS (iPhone, iPad) still supports the older protocol (Hixie) most WebSockets servers support both Hixie and the HyBi/IETF 6455 version. Most other platforms (if they don't already have built-in support) can get WebSockets support via web-socket-js (Flash based polyfill). This covers the vast majority of web users. Also, if you are using Node for the server backend, then consider using Socket.IO which includes web-socket-js as a fallback and if even that is not available (or disabled) then it will fall back to using whatever Comet technique is available for the given browser.
Update: iOS 6 now supports the current HyBi/IETF 6455 standard.
Fast forward to December 2017, Websockets are supported by (practically) every browser and their use is very common.
However, this does not mean that Websockets managed to replace AJAX, at least not completely, especially as HTTP/2 adaptation is on the rise.
The short answer is that AJAX is still great for most REST applications, even when using Websockets. But god is in the details, so...:
AJAX for polling?
The use of AJAX for polling (or long polling) is dying out (and it should be), but it still remains in use for two good reasons (mainly for smaller web apps):
For many developers, AJAX is easier to code, especially when it comes to coding and designing the backend.
With HTTP/2, the highest cost related to AJAX (the establishment of a new connection) was eliminated, allowing AJAX calls to be quite performant, especially for posting and uploading data.
However, Websocket push is far superior to AJAX (no need to re-authenticate or resend headers, no need for "no data" roundtrips, etc'). This was discussed a number of times.
AJAX for REST?
A better use for AJAX is REST API calls. This use simplifies the code base and prevents the Websocket connection from blocking (especially on medium sized data uploads).
There are a number of compelling reasons to prefer AJAX for REST API calls and data uploads:
The AJAX API was practically designed for REST API calls and it's a great fit.
REST calls and uploads using AJAX are significantly easier to code, both on the client and the backend.
As data payload increases, Websocket connections might get blocked unless message fragmentation / multiplexing logic is coded.
If an upload is performed in a single Websocket send call, it could block a Websocket stream until the upload had finished. This will reduce performance, especially on slower clients.
A common design uses small bidi messages transferred over Websockets while REST and data uploads (client to server) leverage AJAX's ease of use to prevent the Websocket from blocking.
However, on larger projects, the flexibility offered by Websockets and the balance between code complexity and resource management will tip the balance in favor of Websockets.
For example, Websocket based uploads could offer the ability to resume large uploads after a connection is dropped and re-established (remember that 5GB movie you wanted to upload?).
By coding upload fragmentation logic, it's easy to resume an interrupted upload (the hard part was coding the thing).
What about HTTP/2 push?
I should probably add that the HTTP/2 push feature doesn't (and probably can't) replace Websockets.
This had been discussed here before, but suffice to mention that a single HTTP/2 connection serves the whole browser (all the tabs/windows), so data being pushed by HTTP/2 doesn't know which tab/window it belongs to, eliminating it's capacity to replace Websocket's ability to push data directly to a specific browser tab / window.
While Websockets are great for small bi-directional data communication, AJAX still carried a number of advantages - especially when considering larger payloads (uploads etc').
And Security?
Well, generally, the more trust and control is offered to a programmer, the more powerful the tool... and the more security concerns that creep up.
AJAX by nature would have the upper hand, since it's security is built in to the browser's code (which is sometimes questionable, but it's still there).
On the other hand, AJAX calls are more susceptible to "man in the middle" attacks, while Websockets security issues are usually bugs in the application code that introduced a security flaw (usually backend authentication logic is where you'll find these).
Personally I don't find this to be that big of a difference, if anything I think Websockets are slightly better off, especially when you know what you're doing.
My Humble Opinion
IMHO, I would use Websockets for everything but REST API calls. Big data uploads I would fragment and send over Websockets when possible.
Polling, IMHO, should be outlawed, the cost in network traffic is horrid and Websocket push is easy enough to manage even for new developers.
In addition to issues with older browsers (including IE9, as WebSockets will be supported starting from IE10), there are still big problems with network intermediaries not yet supporting WebSockets, including transparent proxies, reverse proxies, and load balancers.
There are some mobile carriers that completely block the WebSocket traffic (that is, after the HTTP UPGRADE command).
With years passing, WebSockets will be more and more supported, but in the meantime you should always have an HTTP-based fall-back method for sending data to the browsers.
Most of the complaining I have read about websockets and security is from security vendors of web browser security and firewall security tools. The problem is they don't know how to do security analysis of websockets traffic, because once it has done the upgrade from HTTP to the websocket binary protocol, the packet content and its meaning is application specific (based on whatever you program). This is obviously a logistic nightmare for these companies whose livelihood is based on analyzing and classifying all your internet traffic. :)
WebSockets don't work in older web browsers, and the ones that do support it often have differing implementations. That's pretty much the only good reason why they aren't used all the time in place of AJAX.
I don't think we can do a a clear comparison of Websockets and HTTP as they're no rivals nor solve the same problems.
Websockets are a great choice for handling long-lived bidirectional data streaming in near real-time manner, whereas REST is great for occasional communications. Using websockets is a considerable investment, hence it is an overkill for occasional connections.
You may find that Websockets do better when high loads are present, HTTP is slightly faster in some cases because it can utilise caching. Comparing REST with Websockets is like comparing apples to oranges.
We should be checking which one provides better solution for our application, which one fits best in our use case wins.
An example of the differences between HTTP and Websockets in the form of a client-size lib that can handle Websocket endpoint like REST APIs and RESTful endpoints like Websockets on the client.
https://github.com/mikedeshazer/sockrest
Also, for those who are trying to consume a websocket API on client or vice versa the way they are used to. The libs/sockrest.js pretty much makes it clear the differences (or rather is supposed to).
Well, I have doubts about this technology, more precisely in its implementation, can not find good examples on the Internet, as it involves javascript and php, only, you would have some links where I can find this stuff really works and that ?
A great source for all things Comet is Comet Daily. Unfortunately it's not updated all that often any more but there are some fantastic old articles in there. It's contributed to by guys that have been developing Comet solutions for over 10 years.
Comet seems to get incorrectly bundled as meaning just one particular connection mechanism is used, but it's actually a paradigm for realtime push from server to client. Comet servers can use HTTP Streaming, HTTP Long-Polling, classic polling and WebSockets.
If you are interested in the latest Push Technology then you should take a look at WebSockets which is a standardised approach to not only server to client push, but also bi-directional realtime communication between servers and clients (web browsers and other clients).
Some current trending push technologies are:
socket.io
Hosted WebSockets services such as Pusher - who I work for
Faye for self hosted Ruby or Node dev
SignalR for IIS and .NET
There are many more and more information on realtime web technologies can be found on this guide.
If you want to use PHP you could struggle to build an application using realtime Push which will scale above a small number of connections. Have a read through this question on concurrency - How to implement event listening in PHP for more information.
Do you specifically mean Ajax push? Because a more common method is comet push, I has been a while I worked with this, probably more browsers support this.
A good implementation can be found here:
http://www.ape-project.org/
Well it's called Ajax Push engine, so I suppose that is what you are looking for.
If you work with Java/Scala/Ruby/Groovy, take a look at Atmosphere, which is being actively developed/used (I'm the creator). There are many samples available.
Check out the Bayeux Protocol and CometD implementation in Java & Javascript.
From http://cometd.org/ :
CometD is a scalable HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet.
Here the link to an interesting article describing the technologies involved and a comparison of CometD and Atmosphere implementations.
Socket.IO seems to be the most popular and active WebSocket emulation library. Juggernaut uses it to create a complete pub/sub system.
Faye is also popular and active, and has its own javascript library, making its complete functionality comparable to Juggernaut. Juggernaut uses node for its server, and Faye can use either node or rack. Juggernaut uses Redis for persistence (correction: it uses Redis for pub/sub), and Faye only keeps state in memory.
Is everything above accurate?
Faye says it implements Bayeux -- i think Juggernaut does not do this -- is that because Juggernaut is lower level (IE, I can implement Bayeux using Juggernaut)
Could Faye switch to using the Socket.IO browser javascript library if it wanted to? Or do their javascript libraries do fundamentally different things?
Are there any other architectural/design/philosophy differences between the projects?
Disclosure: I am the author of Faye.
Regarding Faye, everything you've said is true.
Faye implements most of Bayeux, the only thing missing right now is service channels, which I've yet to be convinced of the usefulness of. In particular Faye is designed to be compatible with the CometD reference implementation of Bayeux, which has a large bearing on the following.
Conceptually, yes: Faye could use Socket.IO. In practise, there are some barriers to this:
I've no idea what kind of server-side support Socket.IO requires, and the requirement that the Faye client (there are server-side clients in Node and Ruby, remember) be able to talk to any Bayeux server (and the Faye server to any Bayeux client) may be deal-breaker.
Bayeux has specific requirements that servers and clients support certain transport types, and says how to negotiate which one to use. It also specifies how they are used, for example how the Content-Type of an XHR request affects how its content is interpreted.
For some types of error handling I need direct access to the transport, for example resending messages when a client reconnects after a Node WebSocket dies.
Please correct me if I've got any of this wrong - this is based on a cursory scan of the Socket.IO documentation.
Faye is just pub/sub, it's just based on a slightly more complex protocol and has a lot of niceties built in:
Server- and client-side extensions
Wildcard pattern-matching on channel routes
Automatic reconnection, e.g. when WebSockets die or the server goes offline
The client works in all browsers, on phones, and server-side on Node and Ruby
Faye probably looks a lot more complex compared to Juggernaut because Juggernaut delegates more, e.g. it delegates transport negotiation to Socket.IO and message routing to Redis. These are both fine decisions, but my decision to use Bayeux means I have to do more work myself.
As for design philosophy, Faye's overriding goal is that it should work everywhere the Web is available and should be absolutely trivial to get going with. I'ts really simple to get started with but its extensibility means it can be customized in quite powerful ways, for example you can turn it into a server-to-client push service (i.e. stop arbitrary clients pushing to it) by adding authentication extensions.
There is also work underway to make it more flexible on the server side. I'm looking at adding clustering support, and making the core pub-sub engine pluggable so you could use Faye as a stateless web frontend for another pub-sub system like Redis or AMQP.
I hope this has been helpful.
AFAIK, yes, apart from the fact Juggernaut only uses Redis for Pubsub, not persistence. Also means client libraries in most languages have already been written (since it just needs a Redis adapter).
Juggernaut doesn't implement Bayeux, but rather has a very simple custom JSON protocol
I don't know, but probably
Juggernaut is very simple, and designed to be that way. Although I haven't used Faye, from the docs it looks like it has a lot more features than just PubSub. Being built on top of Socket.IO has it advantages too, Juggernaut's supported in practically every browser, both desktop and mobile.
I'll be really interested in what Faye's author has to say. As I say, I haven't used it and it would be great to know how it compares to Juggernaut. It's probably the case of using the best tool for the job. If it's pubsub you need, Juggernaut does that very well.
Faye certainly could.
Another example of a similar project on top of Socket.IO:
https://github.com/aaronblohowiak/Push-It