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
Related
When using websocket, we need a dedicated connection for bidirectionnel communication. If we use http/2 we have a second connection maintained by the server.
In that case, using websocket seems to introduce an unecessary overhead because with SSE and regular http request we can have the advantage of bidirectionnal communication over a single HTTP/2 connection.
What do you think?
Using 2 streams in one multiplexed HTTP/2 TCP connection (one stream for server-to-client communication - Server Sent Events (SSE), and one stream for client-to-server communication and normal HTTP communication) versus using 2 TCP connections (one for normal HTTP communication and one for WebSocket) is not easy to compare.
Probably the mileage will vary depending on applications.
Overhead ? Well, certainly the number of connections doubles up.
However, WebSocket can compress messages, while SSE cannot.
Flexibility ? If the connections are separated, they can use different encryptions. HTTP/2 typically requires very strong encryption, which may limit performance.
On the other hand, WebSocket does not require TLS.
Does clear-text WebSocket work in mobile networks ? In the experience I have, it depends. Antiviruses, application firewalls, mobile operators may limit WebSocket traffic, or make it less reliable, depending on the country you operate.
API availability ? WebSocket is a wider deployed and recognized standard; for example in Java there is an official API (javax.websocket) and another is coming up (java.net.websocket).
I think SSE is a technically inferior solution for bidirectional web communication and as a technology it did not become very popular (no standard APIs, no books, etc - in comparison with WebSocket).
I would not be surprised if it gets dropped from HTML5, and I would not miss it, despite being one of the first to implement it in Jetty.
Depending on what you are interested in, you have to do your benchmarks or evaluate the technology for your particular case.
From the perspective of a web developer, the difference between Websockets and a REST interface is semantics. REST uses a request/response model where every message from the server is the response to a message from the client. WebSockets, on the other hand, allow both the server and the client to push messages at any time without any relation to a previous request.
Which technique to use depends on what makes more sense in the context of your application. Sure, you can use some tricks to simulate the behavior of one technology with the other, but it is usually preferably to use the one which fits your communication model better when used by-the-book.
Server-sent events are a rather new technology which isn't yet supported by all major browsers, so it is not yet an option for a serious web application.
It depends a lot on what kind of application you want to implement. WebSocket is more suitable if you really need a bidirectional communication between server and client, but you will have to implement all the communication protocol and it might not be well supported by all IT infrastructures (some firewall, proxy or load balancers may not support WebSockets). So if you do not need a 100% bidirectional link, I would advise to use SSE with REST requests for additional information from client to server.
But on the other hand, SSE comes with certain caveats, like for instance in Javascript implementation, you can not overwrite headers. The only solution is to pass query parameters, but then you can face an issue with the query string size limit.
So, again, choosing between SSE and WebSockets really depends on the kind of application you need to implement.
A few months ago, I had written a blog post that may give you some information: http://streamdata.io/blog/push-sse-vs-websockets/. Although at that time we didn't consider HTTP2, this can help know what question you need to ask yourself.
Some pieces of middleware support websockets natively e.g. HiveMQ: http://www.hivemq.com/mqtt-over-websockets-with-hivemq/. What advantages are conferred to a developer using the websockets API as a first class client to the middleware, rather than routing requests through an intermediary server that supports language specific APIs e.g.
Client -> Middleware
vs
Client -> Server -> Middleware
For example, we could argue that skipping an intermediary server will reduce bandwidth costs, not require a developer to write an extra layer, native SSL websockets support?
What other advantages might be provided to not just a developer, but any party through providing websockets support for middleware?
The main advantage you get is simplicity and in case of HiveMQ, scalability.
Let me explain these advantages:
Simplicity
In case of HiveMQ, you just start the server and you are good to go. All web applications which use a MQTT library over websockets can connect to the server without even knowing that websockets as transport is used. For HiveMQ itself, it's just another MQTT client. So it doesn't matter if the clients are connected via websockets or via a classic TCP connection. I think you already mentioned the other arguments in your question. And of course last but not least the operations guys will thank you if they have one system (in your case the "Server") less to maintain.
Scalability
Software like HiveMQ is very scalable and it can handle up to hundreds of thousands of concurrent connected clients. The chance is high, that the additional layer ("Server" in your case) could introduce a bottleneck. Also, things like load balancing with a HW or SW load balancer gets a lot easier if you can throw out unneeded layers. In general, your architecture of your system will get a lot of easier if you don't need these additional layers (which are not services which can be reused for other applications, like microservices are).
Last but not least it's worth noting, that HiveMQ itself is often integrated with classic middleware / ESBs. That means, people write custom plugins for integrating HiveMQ to their existing middleware. JMS or webservice calls (REST, SOAP) are often used for doing that.
Take that answer with a grain of salt, since I'm involved developing HiveMQ :-)
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).
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).
EDIT: I forgot to include the prime candidate for web applications: JSON over HTTP/REST + Comet. It combines the best features of the others (below)
Persevere basically bundles everything I need in a server
The focus for Java and such is definitely on Comet servers, but it can't be too hard to use/write a client.
I'm embarking on an application with a server holding data, and clients executing operations which would affect this data, and thus require some sort of notification across all interested/subscribed clients.
The first client will probably be written in WPF, but we'll probably need to add clients written in other languages, e.g. a Java (Swing?) client, and possibly, a web client.
The actual question(s): What protocol should I use to implement this? How easy would it be to integrate with JS, Java and .NET (precisely, C#) clients?
I could use several interfaces/protocols, but it'd be easier overall to use one that is interoperable. Given that interoperability is important, I have researched a few options:
JSON-RPC
lightweight
supports notifications
The only .NET lib I could find, Jayrock doesn't support notifications
works well with JS
also true of XML-based stuff (and possibly, even binary protocols) BUT this would probably be more efficient, thanks to native support
Protobuf/Thrift
IDL makes it easy to spit out model classes in each language
doesn't seem to support notifications
Thrift comes with RPC out of the box, but protobufs don't
not sure about JS
XML-RPC
simple enough, but doesn't support notifications
SOAP: I'm not even sure about this one; I haven't grokked this yet.
seems rather complex
Message Queues/PubSub approach: Not strictly a protocol, but might be fitting
I hardly know anything about them, and got lost amongst the buzzwords`-- JMS? **MQ?
Perhaps combined with some RPC mechanism above, although that might not be strictly necessary, and possibly, overkill.
Other options are, of course, welcome.
I am partial to the pub/sub design you've suggested. I'd take a look at ZeroMQ. It has bindings to C#, Java, and many other platforms.
Bindings list: http://www.zeromq.org/bindings:clr
I also found this conversation on the ZeroMQ dev listing that may answer some questions you have about multiple clients and ZeroMQ: http://lists.zeromq.org/pipermail/zeromq-dev/2010-February/002146.html
As XMPP was mentioned, SIP has a similar functionality. This might be more accessible for you.
We use Servoy for this. It does automatic data broadcasting to web-clients and java-clients. I'm not sure if broadcasts can be sent to other platforms, you might be able to find an answer to that on their forum.
If you want to easily publish events to clients across networks, you may wish to look at a the XMPP standard. (Used by, amongst other things, Jabber and Google Talk.)
See the extension for publish-subscribe functionality.
There are a number of libraries in different languages including C#, Java and Javascript.
You can use SOAP over HTTP to modify the data on the server and SOAP over SMTP to notify the subscribed clients.
OR
The server doesn't know anything about the subscription and the clients call the server by timeout to track updates they are interested in, using XML-RPC, SOAP (generated using WSDL), or simply HTTP GET if there is no need to pass back complex data on tracking.