I have developed a web app that requires Socket.io to push notifications to users. Given that, is it best to use Socket.io for all communication between the clients and the server or to use ordinary AJAX calls for all communication that doesn't require Socket?
Thanks!
There is no right answer. If you already have a live webSocket connection and you know you will have that, then is is perfectly acceptable to have the client send messages over that webSocket to request data.
Whether you use the webSocket for that or use an HTTP Ajax request is really more a matter of which seems easier to you in both client and server.
A webSocket request "should" be slightly more efficient because the socket is already open and connected (so you avoid the socket setup overhead of an HTTP call). And, if you're running over https, then it has even more setup overhead. But, there exists a lot of useful infrastructure for processing HTTP requests on the server (sessions, templates, lots of middleware, debug tools, proxies, etc...) that might be easier to use for an AJAX call. And, Ajax calls may also be useful as an API when a webSocket is not already open).
There are pros/cons both directions so it really depends upon the type of request, the tools used to fulfill the request and your own preference.
Related
From: https://stackoverflow.blog/2019/12/18/websockets-for-fun-and-profit/
A WebSocket connection is meant to be persisted, so can be overkill for simpler apps.
So when we talk about socket.io which is a wrapper around websockets, we won't have to do heavy work to set up the websocket. So, why is it said that persistent connection can be an overkill for simpler apps?
If you read on, it gives an example:
A WebSocket connection is meant to be persisted, so can be overkill for simpler apps. For a one-directional news feed, metrics feed, or any app where you need to update the client but not receive information in return, Server Sent Events or plain old HTTP calls are quicker and simpler to set up.
Websockets are for when you need the server to be able to send data to the client without the client having to initiate the connection themselves first. In the examples quoted, the client can make the request just once, when the page first loads, or the server can send the data in the initial document.
socket.io can make working with sockets easier, but it still requires setting some stuff up both on the client-side and the server-side; unless you actually require a persistent connection from the server to the client, the setup and the continually open connection won't be accomplishing anything useful.
I'm developing a AngularJS driven SPA. I want to show a fullscreen overlay saying something like "Sorry - Server is not available atm" as soon as the connection between client and server is interrupted.
So I wrote a simple while(true) loop which is basically just calling /api/ping which always returns true. When there is no http response tho, then the message shall appear.
I don't like this approach since it creates a lot of overhead. Especially considering mobile connections.
So what would be a decent solution for my case?
I could imagine work with a websocket and an onInterrupted (or similar) event.
Basically, when an HTTP endpoint is offline you'll receive a HTTP/404 Not found status code.
I would say that it should be better wait for the error rather than querying the server overtime to check if it's online or not.
Use Angular $http provider's interceptors to catch all unsuccessful HTTP status codes and perform an action when you catch one like showing notification to the user to notify that there's no connection available to the server or the server is offline.
With WebSockets you still need to have some sort of ping mechanism, since there is functionally no difference between an inactive/very slow connection and a dropped connection.
Having said that, the overhead regarding wire traffic is much lower, since no HTTP headers are sent on each request, and this will result in lower processing overheads as well.
To use socket.io on the client side, usually we start a node.js server and go like this:
<script src="/socket.io/socket.io.js"></script>
or with specific port:
<script src="http://localhost:3700/socket.io/socket.io.js"></script>
Question is:
is it necessary to use node.js server to serve socket.io.js ?
...or is it possible to
make a local copy of socket.io.js instead of goes to server every single time we need socket.io?
like, we go to view source and copy everything we got from the source of script tag,
paste and save it as socket.io-local.js so that next time we use:
<script src="socket.io-local.js"></script>
will that work ?
Updates
Thanks for everyone's great response,
I'm asking this because in the case I'm involved, I don't actually have access to the server:
I am writing the client-side to connect to other developer's Socket Sever which is written in Java.
Therefore I'll have to think a way to work around the fact that I don't have a server there for me.
from what I've been testing,
this way seems to work but I really don't know what's happening behind the scene.
You obviously can host the socket.io client library anywhere and pull it in to a page. However, it will almost certainly not work with your Java-based server.
To understand why, you need to understand what socket.io is really doing behind the scenes; the client library is only a small part of it.
Socket.io actually defines and implements its own protocol for realtime communication between a browser and a server. It does so in a way that supports multiple transports: if—for example—a user's browser or proxy doesn't support WebSockets, it can fall back to long polling.
What the socket.io client actually does is:
Makes a XHR GET request for /socket.io/1. The server responds with a session ID, configured timeouts, and supported transports.
The client chooses the best transport that the user browser supports. In modern browsers, it will use WebSockets.
If WebSockets are supported, it creates a new WebSocket to initiate a WebSocket connection (HTTP GET with Upgrade: websocket header) to a special URL – /socket.io/1/websocket/<session id>.
If WebSockets aren't supported by the browser or fail to connect (there are lots of intermediaries in the wild like proxies, filters, network security devices, and so forth that don't support WebSocket requests), the library falls back to XHR long polling, and makes a XHR request to /socket.io/1/xhr-polling/<sesion id>. The server does not respond to the request until a new message is available or a timeout is reached, at which point the client repeats the XHR request.
Socket.io's server component handles the other end of that mess. It handles all the URLs under /socket.io/, setting up sessions, parsing WebSocket upgrades, actually sending messages, and a bunch of other bookkeeping.
Without all of the services provided by the socket.io server, the client library is pretty useless. It will just make a XHR request to a URL that doesn't exist on your server.
My guess is that your Java-based server just implements the WebSockets protocol. You can connect directly to it using the browser-provided WebSocket APIs.
It is possible that your server does implement the socket.io protocol – there are a few abandoned Java projects to do that – but that's unlikely. Talk with the developer of your server to find out exactly how he's implemented a "socket server."
A standalone build of socket.io-client is exposed automatically by the socket.io server as /socket.io/socket.io.js. Alternatively you can serve the file socket.io-client.js found at the root of this repository.
https://github.com/LearnBoost/socket.io-client
I have a module called shotgun-client that actually wraps socket.io. I needed to serve a custom client script as well as the socket.io client script, but I didn't want every user of my module to have to include multiple script references on their pages.
I found that, when installed, you can serve the generated client script from socket.io by reading the file /node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js. So my module adds a listener for its own URL and when it serves my custom client script it also serves the socket.io client script with it. Viola! Only a single script reference for the users of my module :)
While this is technically possible, I don't see why you'd need to do that. If you're concerned about reducing the data that goes over the wire, this change won't actually do much beyond the few characters saved in the shorter src tag. Simply changing the location of the JS file on the server won't actually improve performance - the JS has to be sent.
Proper caching (which Socket.IO has) will return a 304 Not Modified (and not re-send the JS file every time you load a page).
This question is for my curiosity only:
Is it possible to make a HTTP request from a backend server to a web browser, that is to say I have a HTTP server ON the web browser to listen for incoming HTTP requests?
Cause I want to use frontend <-> couchdb directly thus dumping the backend server .. but then i wondered how i would do normal processing when the database javascript is not sufficient.
That thought made me think of this question.
Generally speaking — no.
There are some exceptions, Opera has a feature called "Unite" which allows it to run a web server (this is not turned on by default!) as well as acting as a user agent. That wouldn't allow you to send a response to a request that hadn't been made though.
Most web browsers don't have a web server and they are unable to accept HTTP requests. Maybe there is an extension for Firefox, but that's not a typical use case.
Depending on what you are trying to achieve, using Comet or long polling could work for you.
I'm prototyping a realtime notification mechanism using http over port 80. The aim of the project is to allow a Flash application to respond to an event on a remote server quickly (specifically an inbound phone call being connected to a phone next to the computer.) Polling is one approach, but is too slow. Currently I use a socket connection to get low latency notification of the events on the server, which works well but isn't firewall friendly. I don't want to install anything except Flash, or Silverlight on the client. Cross compatibility of browsers isn't a concern - in this application I can specify what browser the client uses but IE is preferred.
I've made a server HttpHandler in .NET which never closes the connection and sends the "events" to the client by writing out bytes to the http response stream (ConnectedClientContext.Response.OutputStream.Write etc) and I have a .NET client application which can read these messages okay.
My Question:
Can I receive the bytes from the server over HTTP as they arrive using JavaScript, Flash or Silverlight? So far I can only find a way to get notified of the "download progress" and don't get the actual bytes until the response is closed - I want them as they arrive.
Best Regards,
Daniel
I don't know about Flash but in Javascript (by which you mean in browser) and Silverlight you are limited pretty much to the http protocol.
You can use the AJAX Http Streaming pattern. The basic ideas which is different from what you are trying is that as soon as data is available outstanding request ends and a new is immediately initiated asychronously, mean while your client process the newly arrived data.
Silverlight gives you more options since is HTTP stack is purely asynchronous but you can get your hands on the stream to you as soon as data starts to arive by setting the HttpWebRequest.AllowReadStreamBuffering to false. (Unlike XmlHttpRequest which always buffers).
it's very easy to use the Comet ideas for notifications. you don't even have to use a comet-specific framework. simply do an ajax request with a callback on answer, wrap this on a loop and you have an event loop, just like a GUI app. on the server side, don't bother answering the request until there's either an event, or a timeout (which is just a 'null' event).
Flex and Flash have several AMF/XML remoting libraries available that support data pushing. I would certainly look into that.
http://raghuonflex.wordpress.com/2008/04/17/data-push-in-flex-with-backend/
These libraries use a Comet - like implementation to achieve this.