Related
I am redesigning a web application which previously has been rendered server side to a Single Page Application and started to read about websockets . The web application will be using sockets to have new records and/or messages pushed to the client. I have been wondering why most pages which make use of sockets don't handle all their communication over the socket. Most of the times there is RESTful backend in addition to the websocket. Would it be a bad idea to have the client query for new resources over the socket? If so why - other than that a RESTful api might be easier to use with other devices?
I can imagine that using websockets would probably not be the best idea in case the network connection is kind of bad like on mobile devices, but that probably should work quite well with a reasonable connection to the web.
I found this related question, however it is from 2011 and seems a little outdated:
websocket api to replace rest api?
No, it won´t be a bad idea. Actually I work in an application that uses a WebSocket connection for all what is data interaction, the web server only handles requests for resources, views under different languages, dimensions .. etc..
The problem may be the lack of frameworks/tools based on a persistent connection. For many years most of frameworks, front and back end, have been designed and built around the request/response model. The approach shift may be no so easy to accept.
Coming back to this question a few years later, I would like to point out a few aspects to illustrate that having all your communication through websockets does have its drawbacks:
there is no common support for compression. You can easily configure your webserver to compress http requests and browsers have been known to happily accept compressed responses for years, however for web sockets it is still not that easy (even though the situation has improved)
client frameworks often are build upon commonly used standards like rest. The further away you move from frameworks expectations, the less addons or features will be available.
caching in the browser is not as easy. By now this goes a long way, reaching into the realm of offline availability and PWAs.
when using technology, that is only used by a subset of users, it is more likely to find new bugs, or bugs might take longer to fix. And if it's not bugs, there might be an edge case somewhere around the corner. This isn't an issue per se - but something to be aware of. If one runs into those things, they often easily take up quite some time to fix or work around.
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).
When we do single page application, the webserver basically does only one things, it gives some data when the client asks them (using JSON format for example). So any server side language (php, ror) or tool (apache, ningx) can do it.
But is there a language/tool that works better with this sorts of single page applications that generates lot of small requests that need low latency and sometimes permanent connection (for realtime and push things)?
SocketStream seems like it matches your requirements quite well: "A phenomenally fast real-time web framework for Node.js ... dedicated to creating single-page real time websites."
SocketStream uses WebSockets to get lowest latency for the real-time portion. There are several examples on the site to build from.
If you want a lot of small requests in realtime by pushing data - you should take a look at socket type connections.
Check out Node.js with Socket.io.
If you really want to optimize for speed, you could try implementing a custom HTTP server that just fits your needs, for example with the help of Netty.
It's blazingly fast and has examples for HTTP and WebSocket servers included.
Also, taking a look at GWAN may be worthwile (though I have not tried that one yet).
http://en.wikipedia.org/wiki/Nginx could be appropriate
I thought about getting rid of all client-side Ajax calls (jQuery) and instead use a permanent socket connection (Socket.IO).
Therefore I would use event listeners/emitters client-side and server-side.
Ex. a click event is triggered by user in the browser, client-side emitter pushes the event through socket connection to server. Server-side listener reacts on incoming event, and pushes "done" event back to client. Client's listener reacts on incoming event by fading in DIV element.
Does that make sense at all?
Pros & cons?
There is a lot of common misinformation in this thread that is very inaccurate.
TL/DR;
WebSocket replaces HTTP for applications! It was designed by Google with the help of Microsoft and many other leading companies. All browsers support it. There are no cons.
SocketIO is built on top of the WebSocket protocol (RFC 6455). It was designed to replace AJAX entirely. It does not have scalability issues what-so-ever. It works faster than AJAX while consuming an order of magnitude fewer resources.
AJAX is 10 years old and is built on top of a single JavaScript XMLHTTPRequest function that was added to allow callbacks to servers without reloading the entire page.
In other words, AJAX is a document protocol (HTTP) with a single JavaScript function.
In contrast, WebSocket is a application protocol that was designed to replace HTTP entirely. When you upgrade an HTTP connection (by requesting WebSocket protocol), you enable two-way full duplex communication with the server and no protocol handshaking is involved what so ever. With AJAX, you either must enable keep-alive (which is the same as SocketIO, only older protocol) or, force new HTTP handshakes, which bog down the server, every time you make an AJAX request.
A SocketIO server running on top of Node can handle 100,000 concurrent connections in keep-alive mode using only 4gb of ram and a single CPU, and this limit is caused by the V8 garbage collection engine, not the protocol. You will never, ever achieve this with AJAX, even in your wildest dreams.
Why SocketIO so much faster and consumes so much fewer resources
The main reasons for this is again, WebSocket was designed for applications, and AJAX is a work-around to enable applications on top of a document protocol.
If you dive into the HTTP protocol, and use MVC frameworks, you'll see a single AJAX request will actually transmit 700-900 bytes of protocol load just to AJAX to a URL (without any of your own payload). In striking contrast, WebSocket uses about 10 bytes, or about 70x less data to talk with the server.
Since SocketIO maintains an open connection, there's no handshake, and server response time is limited to round-trip or ping time to the server itself.
There is misinformation that a socket connection is a port connection; it is not. A socket connection is just an entry in a table. Very few resources are consumed, and a single server can provide 1,000,000+ WebSocket connections. An AWS XXL server can and does host 1,000,000+ SocketIO connections.
An AJAX connection will gzip/deflate the entire HTTP headers, decode the headers, encode the headers, and spin up a HTTP server thread to process the request, again, because this is a document protocol; the server was designed to spit out documents a single time.
In contrast, WebSocket simply stores an entry in a table for a connection, approximately 40-80 bytes. That's literally it. No polling occurs, at all.
WebSocket was designed to scale.
As far as SocketIO being messy... This is not the case at all. AJAX is messy, you need promise/response.
With SocketIO, you simply have emitters and receivers; they don't even need to know about each-other; no promise system is needed:
To request a list of users you simply send the server a message...
socket.emit("giveMeTheUsers");
When the server is ready, it will send you back another message. Tada, you're done. So, to process a list of users you simply say what to do when you get a response you're looking for...
socket.on("HereAreTheUsers", showUsers(data) );
That's it. Where is the mess? Well, there is none :) Separation of concerns? Done for you. Locking the client so they know they have to wait? They don't have to wait :) You could get a new list of users whenever... The server could even play back any UI command this way... Clients can connect to each other without even using a server with WebRTC...
Chat system in SocketIO? 10 lines of code. Real-time video conferencing? 80 lines of code Yes... Luke... Join me. use the right protocol for the job... If you're writing an app... use an app protocol.
I think the problem and confusion here is coming from people that are used to using AJAX and thinking they need all the extra promise protocol on the client and a REST API on the back end... Well you don't. :) It's not needed anymore :)
yes, you read that right... a REST API is not needed anymore when you decide to switch to WebSocket. REST is actually outdated. if you write a desktop app, do you communicate with the dialog with REST? No :) That's pretty dumb.
SocketIO, utilizing WebSocket does the same thing for you... you can start to think of the client-side as simple the dialog for your app. You no longer need REST, at all.
In fact, if you try to use REST while using WebSocket, it's just as silly as using REST as the communication protocol for a desktop dialog... there is absolutely no point, at all.
What's that you say Timmy? What about other apps that want to use your app? You should give them access to REST? Timmy... WebSocket has been out for 4 years... Just have them connect to your app using WebSocket, and let them request the messages using that protocol... it will consume 50x fewer resources, be much faster, and 10x easier to develop... Why support the past when you're creating the future?
Sure, there are use cases for REST, but they are all for older and outdated systems... Most people just don't know it yet.
UPDATE:
A LOT of people have been asking me recently how can they start writing an app in 2018 (and now soon 2019) using WebSockets, that the barrier seems really high, that once they play with Socket.IO they don't know where else to turn or what to learn.
Fortunately the last 3 years have been very kind to WebSockets...
There are now 3 major frameworks that support BOTH REST and WebSocket, and even IoT protocols or other minimal/speedy protocols like ZeroMQ, and you don't have to worry about any of it; you just get support for it out of the box.
Note: Although Meteor is by far the most popular, I am leaving it out because although they are a very, very well-funded WebSocket framework, anyone who has coded with Meteor for a few years will tell you, it's an internal mess and a nightmare to scale. Sort of like WordPress is to PHP, it is there, it is popular, but it is not very well made. It's not well-thought out, and it will soon die. Sorry Meteor folks, but check out these 3 other projects compared to Meteor, and you will throw Meteor away the same day :)
With all of the below frameworks, you write your service once, and you get both REST and WebSocket support. What's more, it's a single line of config code to swap between almost any backend database.
Feathers Easiest to use, works the same on the front and backend, and supports most features, Feathers is a collection of light-weight wrappers for existing tools like express. Using awesome tools like feathers-vuex, you can create immutable services that are fully mockable, support REST, WebSocket and other protocols (using Primus), and get free full CRUD operations, including search and pagination, without a single line of code (just some config). Also works really great with generated data like json-schema-faker so you can not only fully mock things, you can mock it with random yet valid data. You can wire up an app to support type-ahead search, create, delete and edit, with no code (just config). As some of you may know, proper code-through-config is the biggest barrier to self-modifying code. Feathers does it right, and will push you towards the front of the pack in the future of app design.
Moleculer Moleculer is unfortunately an order of magnitude better at the backend than Feathers. While feathers will work, and let you scale to infinity, feathers simply doesn't even begin to think about things like production clustering, live server consoles, fault tolerance, piping logs out of the box, or API Gateways (while I've built a production API gateway out of Feathers, Moleculer does it way, way better). Moleculer is also the fastest growing, both in popularity and new features, than any WebSocket framework.
The winning strike with Moleculer is you can use a Feathers or ActionHero front-end with a Moleculer backend, and although you lose some generators, you gain a lot of production quality.
Because of this I recommend learning Feathers on the front and backend, and once you make your first app, try switching your backend to Moleculer. Moleculer is harder to get started with, but only because it solves all the scaling problems for you, and this information can confuse newer users.
ActionHero Listed here as a viable alternative, but Feathers and Moleculer are better implementations. If anything about ActionHero doesn't Jive with you, don't use it; there are two better ways above that give you more, faster.
NOTE: API Gateways are the future, and all 3 of the above support them, but Moleculer literally gives you it out of the box. An API gateway lets you massage your client interaction, allowing caching, memoization, client-to-client messaging, blacklisting, registration, fault tolerance and all other scaling issues to be handled by a single platform component. Coupling your API Gateway with Kubernetes will let you scale to infinity with the least amount of problems possible. It is the best design method available for scalable apps.
Update for 2021:
The industry has evolved so much that you don't even need to pay attention to the protocol. GraphQL now uses WebSockets by default! Just look up how to use subscriptions, and you're done. The fastest way to handle it will occur for you.
If you use Vue, React or Angular, you're in luck, because there is a native GraphQL implementation for you! Just call your data from the server using a GraphQL subscription, and that data object will stay up to date and reactive on it's own.
GraphQL will even fall-back to REST for you when you need to use legacy systems, and subscriptions will still update using sockets. Everything is solved when you move to GraphQL.
Yes, if you thought "WTH?!?" when you heard you can simply subscribe, like with FireBase, to a server object, and it will update itself for you. Yes. That's now true. Just use a GraphQL subscription. It will use WebSockets.
Chat system? 1 line of code.
Real time video system? 1 line of code.
Video game with 10mb of open world data shared across 1m real-time users? 1 line of code. The code is just your GQL query now.
As long as you build or use the right back-end, all this realtime stuff is now done for you with GQL subscriptions. Make the switch as soon as you can and stop worrying about protocols.
Socket.IO uses persistent connection between client and server, so you will reach a maximum limit of concurrent connections depending on the resources you have on server side, while more Ajax async requests can be served with the same resources.
Socket.IO is mainly designed for realtime and bi-directional connections between client and server and in some applications there is no need to keep permanent connections. On the other hand Ajax async connections should pass the HTTP connection setup phase and send header data and all cookies with every request.
Socket.IO has been designed as a single process server and may have scalability issues depending server resources that you are bound to.
Socket.IO in not well suited for applications when you are better to cache results of client requests.
Socket.IO applications face with difficulties with SEO optimization and search engine indexing.
Socket.IO is not a standard and not equivalent to W3C Web Socket API, It uses current Web Socket API if browser supports, socket.io created by a person to resolve cross browser compatibility in real time apps and is so young, about 1 year old. Its learning curve, less developers and community resources compared with ajax/jquery, long term maintenance and less need or better options in future may be important for developer teams to make their code based on socket.io or not.
Sending one way messages and invoking callbacks to them can get very messy.
$.get('/api', sendData, returnFunction); is cleaner than
socket.emit('sendApi', sendData); socket.on('receiveApi', returnFunction);
Which is why dnode and nowjs were built on top of socket.io to make things manageable. Still event driven but without giving up callbacks.
Of course I am aware of Ajax, but the problem with Ajax is that the browser should poll the server frequently to find whether there is new data. This increases server load.
Is there any better method (even using Ajax) other than polling the server frequently?
Yes, what you're looking for is COMET http://en.wikipedia.org/wiki/Comet_(programming). Other good Google terms to search for are AJAX-push and reverse-ajax.
Yes, it's called Reverse Ajax or Comet. Comet is basically an umbrella term for different ways of opening long-lived HTTP requests in order to push data in real-time to a web browser. I'd recommend StreamHub Push Server, they have some cool demos and it's much easier to get started with than any of the other servers. Check out the Getting Started with Comet and StreamHub Tutorial for a quick intro. You can use the Community Edition which is available to download for free but is limited to 20 concurrent users. The commercial version is well worth it for the support alone plus you get SSL and Desktop .NET & Java client adapters. Help is available via the Google Group, there's a good bunch of tutorials on the net and there's a GWT Comet adapter too.
Nowadays you should use WebSockets.
This is 2011 standard that allows to initiate connections with HTTP and then upgrade them to two-directional client-server message-based communication.
You can easily initiate the connection from javascript:
var ws = new WebSocket("ws://your.domain.com/somePathIfYouNeed?args=any");
ws.onmessage = function (evt)
{
var message = evt.data;
//decode message (with JSON or something) and do the needed
};
The sever-side handling depend on your tenchnology stack.
Look into Comet (a spoof on the fact that Ajax is a cleaning agent and so is Comet) which is basically "reverse Ajax." Be aware that this requires a long-lived server connection for each user to receive notifications so be aware of the performance implications when writing your app.
http://en.wikipedia.org/wiki/Comet_(programming)
Comet is definitely what you want. Depending on your language/framework requirements, there are different server libraries available. For example, WebSync is an IIS-integrated comet server for ASP.NET/C#/IIS developers, and there are a bunch of other standalone servers as well if you need tighter integration with other languages.
I would strongly suggest to invest some time on Comet, but I dont know an actual implementation or library you could use.
For an sort of "callcenter control panel" of a web app that involved updating agent and call-queue status for a live Callcenter we developed an in-house solution that works, but is far away from a library you could use.
What we did was to implement a small service on the server that talks to the phone-system, waits for new events and maintains a photograph of the situation. This service provides a small webserver.
Our web-clients connects over HTTP to this webserver and ask for the last photo (coded in XML), displays it and then goes again, asking for the new photo. The webserver at this point can:
Return the new photo, if there is one
Block the client for some seconds (30 in our setup) waiting for some event to ocurr and change the photograph. If no event was generated at that point, it returns the same photo, only to allow the connection to stay alive and not timeout the client.
This way, when clients polls, it get a response in 0 to 30 seconds max. If a new event was already generated it gets it immediately), otherwise it blocks until new event is generated.
It's basically polling, but it somewhat smart polling to not overheat the webserver. If Comet is not your answer, I'm sure this could be implemented using the same idea but using more extensively AJAX or coding in JSON for better results. This was designed pre-AJAX era, so there are lots of room for improvement.
If someone can provide a actual lightweight implementation of this, great!
An interesting alternative to Comet is to use sockets in Flash.
Yet another, standard, way is SSE (Server-Sent Events, also known as EventSource, after the JavaScript object).
Comet was actually coined by Alex Russell from Dojo Toolkit ( http://www.dojotoolkit.org ). Here is a link to more infomration http://cometdproject.dojotoolkit.org/
There are other methods. Not sure if they are "better" in your situation. You could have a Java applet that connects to the server on page load and waits for stuff to be sent by the server. It would be a quite a bit slower on start-up, but would allow the browser to receive data from the server on an infrequent basis, without polling.
You can use a Flash/Flex application on the client with BlazeDS or LiveCycle on the server side. Data can be pushed to the client using an RTMP connection. Be aware that RTMP uses a non standard port. But you can easily fall back to polling if the port is blocked.
It's possible to achive what you're aiming at through the use of persistent http connections.
Check out the Comet article over at wikipedia, that's a good place to start.
You're not providing much info but if you're looking at building some kind of event-driven site (a'la digg spy) or something along the lines of that you'll probably be looking at implementing a hidden IFRAME that connects to a url where the connection never closes and then you'll push script-tags from the server to the client in order to perform the updates.
Might be worth checking out Meteor Server which is a web server designed for COMET. Nice demo and it also is used by twitterfall.
Once a connection is opened to the server it can be kept open and the server can Push content a long while ago I did with using multipart/x-mixed-replace but this didn't work in IE.
I think you can do clever stuff with polling that makes it work more like push by not sending content unchanged headers but leaving the connection open but I've never done this.
You could try out our Comet Component - though it's extremely experimental...!
please check this library https://github.com/SignalR/SignalR to know how to push data to clients dynamically as it becomes available
You can also look into Java Pushlets if you are using jsp pages.
Might want to look at ReverseHTTP also.