I'm pretty new to web development, so excuse my ignorance.
What I'd like to know is if there's a way to have the server broadcast a message to clients. An example of this would be a client page that has a newsfeed, and every time a new story comes in to the server, the server sends that information out to the client and the client updates its page's newsfeed. I don't want the client to constantly be polling the server every few seconds, asking "hey, is there a new story now? what about now? what about now???" I want the client to be doing its own thing, and then be interrupted by a message from the server.
Is there a way to do this?
For newer browsers, you can use web sockets to open a continuous connection to a server and then client/server can send each other messages whenever they want.
For older browsers, the way this is typically done is that the client has to "poll" the server to ask the server on some regular schedule if the server has any new messages for it. The server usually cannot connect directly to the client because of firewalls, local security settings, unknown location, etc... so the client has to connect to the server. Polling can either be of the regular variety, poll every 60 seconds with an ajax call to ask if there's anything new or it can be more of a long poll where the client asks if there is something new and, if there is something new, the server returns right away with that data. But, there's nothing new, the server hangs onto the polling request for some time period waiting to see if there is something new. Eventually, the server will either return that it has nothing or return with a new message if there is one. When the client gets the response, it starts the "long poll" sequence over again. Comet is an example of the "long poll" in a library form that makes it easier to implement.
Pusher is tailor-made
http://pusher.com/
Related
I need to refresh a part of my view without refreshing the whole page.
At my index.html page I have three panels, wich one shows the number of Tickets by it's status, I need to refresh this number every time a new ticket is created or updated. I used Java with Spring Boot and Thymelaf to build my application.
This is my view:
This is the way I'm doing it now:
model.addAttribute("resolvedTickets", atendimentoService.findAllTicketsByStatus(STATUS_RESOLVED).size());
I have tried to use web sockets but i can't figure out how to get this and refresh the panels.
In a standard web interaction, the client (i.e. your web browser) sends a request to your server. Your server receives the request, and sends back the information to show in your browser and then terminates the connection.
WebSockets are a way to create a persistent, two-way connection between the client and the server, but it requires cooperation from both. A lot of shared servers don't allow WebSockets, so you first have to make sure your server is capable of providing WebSockets. (I see from your screenshot that you're running on Heroku, which should have no problem running WebSockets.)
On the server side, you need to set up handling for incoming WebSocket requests. I don't know what language you've coded your server in, so I can't provide any guidance, but there are plenty of libraries that do the server-side part of WebSockets in most languages.
On the client side, you need to set up your WebSocket client. MDN has a great guide on WebSockets that explains what you'll need to do. Basically, all you'll have to do is listen for incoming messages and increment your counter.
var count = 0;
var exampleSocket = new WebSocket("ws://example.com/socket");
exampleSocket.onmessage = function(event) {
count++;
document.getElementById('myTicketCounter').innerHTML = count;
}
For some things, WebSockets are overkill. If you find that this is too much work for too little reward, you can also just set up an AJAX call to fire every few minutes that pings another page on your server and returns the number of tickets and updates accordingly. It won't be instantaneous, but if you don't need down-to-the-second resolution, it'll probably suffice. You can adjust the interval to be as long or as short as you want (to an extent; bombarding your server with constant requests will slow you down a bit).
I have a 3rd party service to implement, that provides restful API with long polling... they are serving live events, and displaying it as quick as possible is crucial.
Sadly that service does not provide push notifications, so we need to deal with what we have....
so one of the APIs has a long-polling functionality, so in theory the idea is, I query the API, establish an open channel for 30 seconds and wait for the changes... (and publish the changes on the FE)... and then timeout the connection, establish a new one and repeat the process.
Should be pretty straight forward....
But so far, I couldn't find anything in angular's docs about long polling... the only thing I found was polling in connection with rxJS... so setting an inteval on how often I query the API... (which in my case would be every 30s)... but nothing about on leaving the channel open and listen for the changes...
found this thred:
How to implement http long polling in Angular 2
but it is not talking about this problem.
I don't want to end up querying the API every second.
Any ideas?
I considered implementing signalR (which might not really help here), but it relies on jQuery... which I don't want to add to the bundle unless is 100% necessary!
I think you misunderstood the concept of long-pulling..
Long-pulling where the client polls the server requesting new information. The server holds the request open until new data is available. Once available, the server responds and sends the new information. When the client receives the new information, it immediately sends another request, and the operation is repeated. This effectively emulates a server push feature.
It you want to keep the connection alive you need to use webSoket.
WebSockets provide a persistent connection between a client and server that both parties can use to start sending data at any time. The client establishes a WebSocket connection through a process known as the WebSocket handshake. This process starts with the client sending a regular HTTP request to the server
But I didn't understood from your question why you can't send another fetch request when the long-pulling completes, something like:
myLongPullingFunc(){
this.http.get(longPullingURL)
.subscribe(res=>{
if(sholdFetchData){
useFetchedData(res);
this.myLongPullingFunc();
}else
doSomethingElse()
})
}
You can read more about long-pulling here and on webSokects here
I have a node.js server which is communicating from a net socket to python socket. When the user sends an asynchronous ajax request with the data, the node server passes it to the python and gets data back to the server and from there to the client.
The problem occurs when the user sends the ajax request: he has to wait for the response and if the python process takes too much time then the ajax is already timed out.
I tried to create a socket server in node.js and a client that connects to the socket server in python with the data to process. The node server responds to the client with a loading screen. When the data is processed the python socket client connects to the node.js socket server and passes the processed data. However the client can not request the processed data because he doesn't know when it's done.
So you have three systems, and an asynchronous request. I solved a problem like this recently using PHP and the box.com API. PHP doesn't allow keeping a connection open indefinitely so I had a similar problem.
To solve the problem, I would use a recursive request. It's not 'real-time' but that is unlikely to matter.
How this works:
The client browser sends the "Get my download thing" request to the Node.js server. The Node.js server returns a unique request id to the client browser.
The client browser starts a 10 second poll, using the unique request id to see if anything has changed. Currently, the answer is no.
The Node.js server receives this and sends a "Go get his download thing" request to the Python server. (The client browser is still polling every 10 seconds, the answer is still no)
The python server actually goes and gets his download thing, sticks it in a place, creates a URL and returns that to the Node.js server. (The client browser is still polling every 10 seconds, the answer is still no)
The Node.js server receives a message back from the Python server with the URL to the thing. It stores the URL against the request id it started with. At this point, its state changes to "Yes, I have your download thing, and here it is! - URL).
The client browser receives the lovely data packet with its URL, stops polling now, and skips happily away into the sunset. (or similar more appropriate digital response).
Hope this helps to give you a rough idea of how you might solve this problem without depending on push technology. Consider tweaking your poll interval (I suggested 10 seconds to start) depending on how long the download takes. You could even get tricky, wait 30 seconds, and then poll every 2 seconds. Fine tune it to your problem.
I have PHP on the server side, and HTML and javascript on the client side.
I am making an app where a stakeholder types a message that is broadcasted to multiple recievers of a group in real time.
I did some research on google and I understand I need to use WebSockets or Comet for real time push notifications. Is WebSocket or Comet mandatory for sending mass notifications to users?
Is my understanding correct? Any references to start with?
If the client is a browser, then the ONLY two ways a standard browser can connect to a server is via an Ajax (e.g. http) request or a webSocket connection. So, if you want a client to get notified of something from the outside world it has to use one of those two mechanisms.
HTTP requests are transitory. The client makes a request of a server, the server responds. HTTP requests are perfect for the client requesting information from the server. They are not very good at the server sending information to the client because normally the client is not connected. There are hacks and work-arounds where the client "polls" the server on some interval and maybe even the server uses longer running requests to try to simulate a "push" type system, but they are sub-optimal hacks at best.
webSockets are continuous connections. The client connects and the connection remains in place for as long as both sides want. This allows either side the ability to send a message to the other side whenever they want. That means the server can "push" data to the client whenever it wants. webSockets are efficient for push connections and are recommended (this is one of the main things they were designed for).
Comet is a library that was originally built for using HTTP to try to "hack" or "simulate" push before webSockets were invented and then before they were widely supported. I can think of no reason why one would want to use Comet instead of a webSocket unless you had such an old browser that webSocket was not supported.
So, if you are trying to do "realtime server push" to a browser, then you must have a continuously connected socket from the client which means webSocket (or something built on top of webSocket like socket.io).
For phone apps where you have access to the phone SDK, you can use the "push" system built into the OS to push some messages from server to client. This isn't quite the same as the two way webSocket channel, but since you asked about "push notifications", the OS push services available in both Android and IOS could also be an option for pushing notifications from server to client. Here's info on iOS notifications and Google Cloud Messaging
As of 2016, one can also use Server-sent events in all modern browsers except Microsoft browsers (not supported yet in Edge or IE) to push data from server to client. Here's a browser compatibility table. Server-sent events use a long lasting HTTP connection, a special MIME type and a supporting client in order to be able to send events from server to client at any time. Unlike webSockets, server-sent events are one way only (from server to client). A client would then use a traditional Ajax call in order to be able to send data to a server (whereas with a webSocket data can be sent either way over the same webSocket connection).
Here's a good description of how server-sent events work: How do server-sent events actually work?
Is your client application a SPA? (Single Page application)?
It's very important because if not, you have to consider that everytime a client change page, connection with websocket server will be lost.
In this case you have to manage a queue because if stakeholder send a multicast request when one client is disconnected, client won't receive nothing.
Polling won't solve this situation too and it's an orrible solution because mobile clients (for example) with typical internet plan, will consume megabytes for unuseful "ping" traffic.
A real example of polling is a child in a car asking his dad every minute if they are arrived to a destination!
So, Is there a solution without using spa?
Yes, using a "shared storage" between stakeholder and clients, and using websocket only for "wake up" online clients saying: Hey there is something new, go to check!
Everytime a client open a page it will receive from backend also not-read notifications, taken from the storage.
When a stakeholder want to notify something, it will just store the notification message in the shared storage and send a "pulse" to notification server.
Notification server will forward the "pulse" to online clients (just in case someone is stuck reading a page).
If a "pulse" is lost because a client is changing page there is no problem because the client will bring notifications from the storage.
Every page will contain this logic:
Retrive number or unread notifications (server side)
Connect to the notification server after 5 seconds (javascript side).
Hope it helps.
I would suggest that using webSockets is a more efficient way compared to other options, why is this? Well when a client receives a notification that there's a change in the server there is no need to create an AJAX call to the server to get that change, it can be sent to the client with the same webSocket connection more easily than AJAX. This means efficient code and a faster running App!
I'm using node.js to have multiple clients. Now, in my code, I'm listening on a port and each time a client connects, I want to send out a broadcast message to all other clients, say. I'm raising a new event each time some new client connects, and I'm sending a response over to him. When I say response.end(), I'm not able to send anything to that specific client after that. However, the browser keeps loading and waiting for the response.end.
Is there anyway around this without using socket.io?
I know socket.io has its uses, but I really wanted to know if I can do it without socket.io.
I'd say to use two channels in your client; one to receive updates (channel kept open, or frequently querying for updates) and one to refresh the data. It involves some work on your part to restructure the client and the server, but I think using two channels is the cleanest way to solve your problem.
If you don't send the .end() the browser will keep waiting. But if you close the channel you'll not be able to send nothing through it. So, either use socket.io or open a channel via XHR and keep it open for each client to receive messages. Is up to you to adequately frame the messages (implement your applicative protocolo) though. I think Paul is right.
Try long polling, which means letting an ajax request from the browser 'hang' until the server can send something back.
How do I implement basic "Long Polling"?
Using nodejs, you could store the response objects for the clients easily.