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.
Related
I am currently working on an instant messaging system. But, I have a problem with the optimization.
Here is my current code:
<script>
setInterval('load_messages()', 500);
function load_messages(){
$('#messages').load('loadMessages.php');
}
</script>
Apart from the fact that, it is better to use an AJAX request to ask only for messages after a defined timestamp. Is there a way to pass a packet from the sender's page to the receiver to refresh to avoid spamming the database.
Here is a schema explaining what I would like to do:
Is there a way in php, apache or javascript to do this?
Thanks for reading
The technique you use is called short-polling. It's basically spamming the server until the server has something new to show you. Looks something like:
Client: cookie?
Server: no
Client: cookie?
Server: no
Client: cookie?
Server: no
Client: cookie?
Server: yes; here's the cookie: 🍪
Client: cookie?
Server: no
...
This is really inefficient, as you understood yourself; I don't know of any websites that still use short-polling.
You have other options. The easiest one (given you are using PHP) is long polling. Basically, you send a request, and the server just stalls the request, and once a new message comes the server sends the response back. This allows you to get messages immediately and not send so many messages:
Client: tell me when you have a cookie...
[loads for 1m 32s]
Server: the cookie has come [sends response]
Client: tell me when you have a cookie...
...
However, Apache handles concurrent requests by creating a new thread per request. So if you have 2 users in your chat, that's fine. But let's say you have many rooms and a total of 100,000 users long-polling your server. Your server probably can't handle that many threads and will crash. (NodeJS is very popular for realtime applications for its event-driven architecture and built-in asynchronism.)
But there are other much, better, options:
Websockets: this is basically a persistent (that is until the connection is manually closed) connection between the client and server, so the client doesn't have to bug the server so much. Whenever the server has a message, it sends it to the client immediately and vice versa. Here's a good article. This is the most popular solution to realtime apps, and implemented by most chat apps like Discord or Slack.
SSE (server sent events): basically, instead of the client asking the server for data, the server can send data to the client. Here's another article if you want to know how it works.
Your context: SSE is quite easy to implement in PHP without extra libraries; here's an example. Websockets, on the other hand, are a bit more complex to set up (may require a third-party library like rachet), but because of how well it works that's probably what I would consider.
Your question: Is there a way to pass a packet from the sender's page to the receiver to refresh to avoid spamming the database? If I were to exactly answer your question, SSE.
As we know, if running application also manage sessions in main memory then is there any way for server to send responses to all web clients/browsers for new recorded data in a database.
Remember: I have not made any request to server or polling to server for new records update..
Let server make responses without web request..
Objective :
No all web browsers making request or polling to server for every certain interval therefore reducing the performance issue with the application memory..
Am just against of making so many ajax calls from every web client..
Need your ideas from your past, if experienced similar..
read about websockets and socket.io.
basically with socket.io you have a connection open between browser (client) and server and server can send data which the client than receives as an event.
the client doesn't need to send a request to get that data, only open the web socket connection.
you can look at socket.io chat example: http://socket.io/get-started/chat/
WebSocket is the best and easy solution if you don't want to go through the hassle to learn Angular or others.
Both server-side and client-side can build WebSocket, and it acts as a bridge to transmit data back and forth.
I just created an easy solution for this.
Please check my new library wsm - WebSocket Manager, it works for both server-side and client-side.
Websocket Server can be built easily; this library includes several useful features.
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.
I'm creating an app where the server and the clients will run on the same local network. Is it possible to use web sockets, or rather more specifically, socket.io to have one central server and many clients that are running native apps
? The way I understand socket.io to work is that the clients read the web-pages that are served from the server but what happens when your clients become tablet devices running native apps instead of web pages in a browser?
The scenario I'm working with at the minute will have one central server containing a MEAN app and the clients (iPads) will make GET requests to the data available on the server. However, I'd also like there to be real-time functionality so if someone triggers a POST request on their iPad, the server acknowledges it and displays it in the server's client-side. The iPad apps will (ideally) be running native phonegap applications rather than accessing 192.168.1.1:9000 from their browser.
Is this technically possible to connect to the socket server from the native apps or would the devices have to send POST requests to a central server that's constantly listening for new 'messages'? I'm totally new to the whole real-time stuff so I'm just trying to wrap my head around it all.
Apologies if this isn't totally clear, it's a bit hard to describe with just text but I think you get the idea?
Correct me if I am wrong.
You have multiple iPads running native app. They send a POST request to your node JS server which is running in a computer in the same local network. Whenever the server receives a request from app, you want to display that a request has been received in your computer screen.
If my assumptions about the scenario is correct, then it is fairly easy to do. Here are the steps to do it.
Create a small webpage (front end). Load socket IO in the front end page like this -
<script type="text/javascript" src="YOUR_SERVER_IP/socket.io/socket.io.js"></script>
Then connect to server using var socket = io(). This should trigger connection event in your backend.
Handle all POST request from apps normally. Nothing special. Just add a small snippet in between. socket.emit('new_request', request_data). This sends new_request event to front end.
Handle the new_request in your front end using socket.on('new_request', function(request_data) { ... });. That's it. No need to add anything to your native app for realtime update.
The second step would be a little complicated as it is necessary to make socket variable available inside all POST requests. Since you chose node.js, I don't think you need any help with that.
Not totally clear on your project, but I'll try to give you some pointers.
An effective way to send data between native apps and a server is using a REST server. REST is based on HTTP requests and allows you to modify data on the server, which can connect to your database. The data returned is typically either JSON or XML formatted. See here for a brief intro: http://www.infoq.com/articles/rest-introduction
Android/iOS/etc have built in APIs for making HTTP requests. Your native app would send a request to the server, parse the response, and update your native UI accordingly. The same server can be used from a website using jQuery ajax HTTP requests.
Express.js is more suited to serving web pages and includes things like templating. Look into "restify" (see here: mcavage.me/node-restify/) if you just want to have a REST server that handles requests. Both run on top of node.js (nodejs.org).
As far as real-time communication, if you're developing for iOS look into APNS (Apple Push Notification Service). Apple maintains a persistent connection, and by going through their servers you can easily send messages to your app. The equivalent of this on Android is GCM (Google Cloud Messaging).
You can also do sockets directly if that's easier for you. Be careful with maintaining an open socket on a mobile device though, it can be a huge battery drain. Here's a library for connecting ObjC to Socket.IO using websockets, it may be useful for you: https://github.com/pkyeck/socket.IO-objc
Hope that helps!
To answer your question, it is definitely possible. Socket.io would serve as the central server that can essentially emit messages to all of the client. You can also make Socket.io listen for the messages from any of the clients and serve the emitted message to the rest of the clients.
Here's an example of how socket.io can be used. Simply clone, npm install, and run using 'node app.js'
All you have to do is to provide a valid server address when you connect your socket from the iPad clients:
var socket = io.connect( 'http://my.external.nodejs.server' );
Let us know if you need help with actual sending/receiving of socket events.
It is possible to connect to Websockets from your apps.
If you are using PhoneGap then you need a pluging that gives support to websockets in your app (the client) and then use websocket like normal way using Javascript see this.
If your app is native iOS look into this it could help you.
The primary use of the Sockets in your case is to be a bidirectional "pipe" between an app and server. There is no need of server sending the whole web-page to the native app. All what you need is to send some data from server to the client(app) in response to POST (or GET) request and then using this data on client side to update client's UI in real-time. If you are going to use moderate amount of devices (say tens of them), you may have connected all of them to the server permanently keeping individual socket connection open for every individual link server-to-app. Thus you may deliver data and update client's state in real time.
In fact web browsers also employ sockets to communicate to web servers. However as in general case there is no control on amount of concurrent clients in Internet, for the sake of limited networking resources conservation, servers do not keep sockets open for a long time, closing it just after the web-page was sent to client (or timeout has expired). That's how HTTP protocol works on the low level. The server waiting for the HTTP clients (browsers) by listening the 80 port, responding them by sending the whole web page content, then closing the connection and keep waiting for another requests on the same port.
In your case it's basically a good idea to use socket.io as it's a uniform implementation of sockets (ok WebSockets) on both client and server side. The good starting point is here
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).