I'm building a webpage with some interactions between users and I'm a bit lost.
Any guidance is welcome.
Imagine the following scenario:
Client A opens a 'public' webpage and pressess a button.
Client A starts waiting for the response of client B
Client B goes to an 'admin' webpage and presses a button.
Client A receives the information that client B had pressed a button.
The overall idea to have a page were client A can click a button "I'm ready to play" and starts waiting for client B's response. Client B receives a notification and presses a button "I'm ready too". Client A receives a notification telling Client B is ready too.
I know this could be done with AJAX. But I'm not really sure how to 'wait' for the client B response and update the webpage when the response arrive.
Any help / tip is welcome.
Thanks for your support.
Asynchronous
You seem to think in synchronous way, but that's not how you should think about this. You are issuing a command to the server, but you should not wait for the response, because:
the command might never arrive, for ex. due to Internet connectivity issues
the server might be down
the server might error out your command and never respond
the other player might never receive the message
the other player might never answer the message
the server might never receive the other player's command
the server might error out the other player's command
the server might never send you the notification
you might never receive the notification
So many point of possible failure on the one hand. And... Javascript is single-threaded on the other hand. So, if you wait for the other player to respond, then your UI will froze in the meantime (with the exception of Web Workers, but that's a more advanced topic, for now, let's view Javascript as a single-threaded environment)
Instead you should think asynchronously. In fact, in the achronim of AJAX, the first "A" stands for "Asynchronous". This means that you issue a request and define what you will do when a response is received. This "what will you do" is called the callback. Your client-side will work and be responsive in the meantime and when a response arrives it will know what to do.
Not only your request, but the other's response
Okay, now that we think asynchronously, we need to consider our options to handle when the other player decides to join your game:
Polling
You may issue periodic requests to the server via setTimeout and AJAX requests and once the response notifies you about the game being accepted, handle it accordingly. See: https://davidwalsh.name/javascript-polling
Push notifications
The server may send notifications to the users once an event occurs. See: https://onesignal.com/lp-web-push?utm_source=google&utm_medium=cpc&utm_campaign=general&gclid=CjwKCAjw4_H6BRALEiwAvgfzq9s03BR1OhlvxwN6SCn6Q_bIKODk3bQK05gwdaHTpwvzV2d7mXQU9hoCSl4QAvD_BwE
But you may want to use something that's compatible with what you are using at the server.
WebSockets
WebSockets are duplex channels, which are kept open. If the framework is implemented and supported, then client A and client B would both be connected, client A would send a command via WebSocket, the server would receive that and notify client B via WebSocket. When client B decides to accept the challenge, he would click on the button, which would issue a command of his own to the server via WebSocket and the server would notify client A via WebSocket. See: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
Summary
It's better to view this as a series of events and event handlers, rather than waiting for a response.
Related
I have an issue - I should update information for user as soon as possible, but i don't know exact time when it'll happen.
I use setInterval function that checks differences between current state and the state before checking. If there are any differences then I send an AJAX request and update info. Is it bad? I can't (or don't know how to) listen any events in that case.
And what about interval time? All users (~300 at the same time) are from local network (ping 15-20 ms). I have to refresh information immediately. Should I better use 50ms or 500ms?
If the question is not very clear just ask - I'll try to say it in other words.
Thanks in advance
Solution: Websocket
Websockets allow client applications to respond to messages initiated from the server (compare this with HTTP where the client needs to first ask the server for data via a request). A good solution would be to utilize a websocket library or framework. On the client you'll need to create a websocket connection with the server, and on the server you'll need to alert any open websockets whenever an update occurs.
The issue with interval
It doesn't scale, you could set the interval to 4000 miliseconds and still once you hit 1000 users...you are going to be slamming your server with 10000 requests and responses a minute...This will use tons of data and use processing to return nothing. Websockets will only send data to the client agent only when the event you want to send actually occurs.
Backend: PHP
Frameworks
Ratchet
Ratchet SourceCode
phpwebsocket
PHP-Websockets-Server
Simply implement one of the above frameworks as a websocket connection then you will register as a client to this endpoint and it will send data on whatever event you define.
How can i get latest or fresh data from server (if in server happened new event (for example there are 2 users x,y and x send messages to y and y get this message without refreshing page ) )?
I don't want to use setInterval because it repeats all message again and again. Is there any Technique that can i use for this ?
I heard about Ajax that technique need to send request to the server but i want when happen an event in the server and webpage get it without refreshing..
The first technique is the long polling, which sends request to the server and waits until the server sends something, for example the new message. You must re-send requests to the server each time you get a new message or your request is time out. This technique uses AJAX.
Long polling PHP example - How do I implement basic "Long Polling"?
The second is web sockets, https://en.wikipedia.org/wiki/WebSocket
this stackoverflow question deals with the implementation of websocket.
socket.io has a demo of chat application.
If you looking for bidirectional full duplex method then go for WebSockets but for just polling data from server you can use Server Sent Event as well. Adding reference links for both:
WebSocket:
http://html5demos.com/web-socket
http://en.wikipedia.org/wiki/WebSocket
HTML5 Websockets for Realtime Chat app?
SSE:
http://www.html5rocks.com/en/tutorials/eventsource/basics/
Examples:
SSE: http://demo.howopensource.com/sse/
I'm going to write an application, having some worker threads on the server, and some log and status elements on the html page. logs and status are expected to be updated whenever an update is ready from the server side.
well, one approach is to set up a polling mechanism, like the client sends a request on specified intervals and the server sends back the last update, (if any available).
however I wonder if there is any more efficient way like an interrupt-driven approach, on which whenever an update is ready on the server a message is sent to the client through an Ajax call. and as long as no update exists no message is transferred back and forth.
first of all, is this possible to initiate a call from the server side? I mean via Ajax.
or is there any library like JQuery that facilitates such a requirement?
Thanks
Consider using web sockets (Available in HTML5) - This will allow you to skip polling an update the data immediately as the server sends up his finish request.
Read more on:
http://www.html5rocks.com/en/tutorials/websockets/basics/
In my ASP.NET MVC app, the user clicks a button on the UI to make a phone call. An ajax request goes to the MVC app, which calls a phone dialer -- a method in library that calls an external component to make a call.
If a dialed call is terminated by the recipient of the call, the phone dialer component raises an event by calling an event handler in its own class.
I want to propagate that event to the client side so that it may update its UI.
An Option I Can't Use
I've looked at JavaScript Server-sent events. However, they are different from my situation in the way that in a JavaScript Server-sent event, here's what happens:
1) The client initiates a connection on a new socket to the server. The key difference being, the client initiates the connection.
2) The connection is held live and active until the server or the client want to terminate it.
3) The server has to be alive all throughout the time from the time the connection is made until the client or the server want to terminate the connection and no longer exchange notifications. This means that a new socket connection and consequently a new worker thread to service the notification exchange is used per client.
If I use server-sent events, I will have to make a server that stays alive. That means I will have to have a new action on a controller and a corresponding view that gets called at the very beginning and stays alive until the notification about the call hang-up is received.
This can not only be expensive, it is also counter-intuitive to my design as I do not want to be redirected to a new View just to listen to events.
Anyone have any other alternative?
You have to either use a WebSocket or Long polling. These both require you to set up a connection from the client to the server, additional to the normal HTTP cycle. And what else would you expect? When the page is sent, the communication between client and server is done. The HTTP cycle is over, no more data can float through. The new connection needs to originate from the client because the client does not allow arbitrary incoming connections.
I do not think there are other alternatives in normal case.
SignalR, etc, all require connection to be alive or periodically restarted by client. I am not aware of anything that allows server to initiate connection with a browser (it does not even seem technically possible due to proxies/firewalls etc).
I've recently taken over a project that uses COMET to perform some collaborative work and handle a simple chat room. The guys who originally wrote this thing made up some classes on top of STOMP and Oribited to handle all the actual chatting and messaging and logging.
The problem is that if a user closes the window or navigates to a different page or terminates the connection for whatever other reason, it takes a while for all the other users to see that he has logged off. The other users have to wait for the timestamp of the exited-user's last ping to exceed a certain duration before it registers that the user is no longer connected to the system.
The solution that I can think of requires sending out a notification in the onuload event that the user has left, so that it would notify all the other users without having to wait for a timeout. The problem with this is that since onunload will immediately terminate the connection before it's completed. From what I understand this is a problem with AJAX as well.
Now, I also have read that a Synchronous request in unload will delay the window-close/navigation until the request has finished.
So, my questions is this: does anyone know of a way to temporarily make the comet request synchronous in selected instances so it has time to finish the request before terminating? Or is there another way to solve this problem that I'm not thinking of? Thanks for your help.
Oh, also, onbeforeunload won't work because if it sends the request and the user selects "No, I want to stay on this page" it will have already have notified the other users that he has exited the chat.
tl;dr: Need a way to successfully fire a COMET request in the Unload event. We're using STOMP and Orbited for the COMET stuff.
The 'onbeforeunload' function produces a yes-no dialog only if some value is returned from it. So what you have to do is to use a SYNCHRONOUS XMLHttpRequest (AJAX) request inside the onbeforeunload function without returning anything. And you have to set the asynchronous flag of the request to false as seen in the AJAX GET request shown below:-
AJAXObject.open("GET", 'http://yourdomain/logout?somevar=something', false);
AJAXObject.send(null);
It will prevent the browser from closing until request completes and as I remember, Opera doesn't support 'onbeforeunload', so it won't work for Opera. But it works fine on IE,FF,Chrome.
If you are using comet, then you should control the server. The idea with comet is that it is not constant polling of the server. Every client should have a constant open connection to the server. As such, when the connection closes, the server should be able to send out a notification to the other clients.