I wanted to create a web chat. It was suggested that i use Php Socket Servers. I've made one and they function well with a telnet client.
What i find myself bamboozled by is how to get that data to the client via ajax (no page refreshes).
All I can come up with is calling a php file with ajax, getting the data and updating the page. But that will not work the other way around.
Or am i missing something?
How would you implement a 1 on 1 web chat?
One solution is long-polling. The client will open up an AJAX request to a script that will block and wait for data to come in. If no data comes in within a minute, it will return and the client will reopen the connection. If data comes in, then it will immediately return the data and the client will update its view.
For sending the data, just do a normal AJAX callback.
You've got the idea of client-initiated communication, which is fine for sending things from the client to the server.
As a consequence of the stateless nature of HTTP, there is no way to "push" data, unbidden, to the client.
The way you get around this is by always leaving a connection back to the server open. The request is pending, and when the server has something to say, it responds to the pending request. Whenever this happens, the client creates a new request to leave sitting until the next time server->client communication must happen.
Another way to implement near-real-time communication is through frequent polling. But I don't recommend this approach, really. Especially not for a chat program.
Related
I'm trying to understand the event loop in Node JS. There are fantastic resources online but i keep finding myself wondering the same thing. The scenario is below:
For Javascript/Node
On a web page with a getData button.
The user clicks the button and a request is sent to the server to the getData route (in this simplified scenario when the server gets the data it returns a new page showing the data). The data request is asynchronously offloaded to a Node API (and out of the call stack).
Before the api returns the data the user changes pages in the browser, a new http request is sent to the server for a different page and this fires an http.get(url, callback) adding the new page to the callback queue to be loaded (this beats the data request and the new page is returned).
What happens to the old callback for the now redundant data? Presumably when the event loop reaches the getData callback in the cb queue, it will attempt to run the callback function. Will Node send a response to change the page again with the data displaying page? If it was Ajax and the data returned after a page change what happens to the callback in this scenario, does ajax simply ignore the returned data on the new, different page?
I know Ajax handles on page updates but i wanted to simplify to understand how the event loop handles situation where the call stack has moved on and the older callbacks are no longer useful.
Thankyou for the responses they have been very useful! The only thing that i would add is (and i understand this scenario requires very bad server design but the theory is my interest here) if the server does respond with a page that is no longer wanted by the user (due to the delay in async response), does the browser understand that this is not the most recent request? I think as http is stateless the browser will receive the response over TCP and reload with the previously requested page (to the the clients frustration).
Many thanks!
Pretty sure the browser discards the response because the request itself is closed. It depends on the timing, the server (forget whether it's node.js or apache or anything else) might still get the response in time to try to respond to it. If it does respond to it, it doesn't care what the browser does with the response.
You say
The user clicks the button and a request is sent to the server to the getData route (in this simplified scenario when the server gets the data it returns a new page showing the data). The data request is asynchronously offloaded to a Node API (and out of the call stack)
The browser is oblivious of the server's implementation. It doesn't care how the server responds as long as it tries to respond. At the same time, the server is also oblivious of the "state" of the browser. All the server knows is that there is an open request that it needs to respond to and does so. Once it has responded, it doesn't care.
I know Ajax handles on page updates but i wanted to simplify to understand how the event loop handles situation where the call stack has moved on and the older callbacks are no longer useful.
There is no movement of the callstack, the server received a request and as long as that request is open, the server should respond to it. If another request comes in (even if the new request is nearly identical) the server will also respond to that request separately.
In a simplified HTTP request scenario, a connection is established between client (eg Web browser) and server first, using TCP.
HTTP is sent over this link to configure the exchange of data.
The TCP connection is maintained until either end closes it (usually client says "Thanks! All done!"). So the TCP connection remains open while the Node.js process fetches some data asynchronously.
If a user gives up waiting for a response and (say) closes the browser, then the TCP connection is closed on both ends. Meanwhile, the callback for the database call continues to exist in server memory, ready for when the DB returns. The DB then returns, the callback is run, and as soon as the callback attempts to send data back to the client over the TCP connection it will discover it has been closed and a suitable error will be raised (and possibly caught) on the server-side.
The callback then exits, the stack frame is popped off the stack, the memory allocated to the stack frame is freed, and control returns to the previous frame. When the garbage collector in the Node.js JavaScript runtime next runs, any objects solely linked to that no-longer-in-existence frame are swept up and the memory associated with them is freed.
In an unhappy-path scenario (eg. power plug pulled on the client computer), then the server will think the TCP connection is still open for a configurable period, until it times out, or it discovers it is unable to successfully send data across it, at which point the server closes it and cleans up the associated memory.
This can be complicated by the concept of HTTP keep-alive, which involves the browser and server agreeing to use a single TCP connection for multiple HTTP requests to save time. Under HTTP keep-alive, the HTTP protocol is leveraged to ensure the browser will safely ignore any data returned over the TCP connection that corresponds to a no-longer active request.
And there is an even more modern technique of multiplexing several concurrent HTTP requests over the same TCP connection too, but that is outside the scope of this question.
I think.
I've seen how to make a post request from JavaScript to get data from the server, but how would I do this flipped. I want to trigger a function in the flask server that will then dynamically update the variable on the JavaScript side to display. Is there a way of doing this in a efficient manner that does not involve a periodic iteration. I'm using an api and I only want to the api to be called once to update.
There are three basic options for you:
Polling - With this method, you would periodically send a request to the server (maybe every 5 seconds for example) and ask for an update. The upside is that it is easy to implement. The downside is that many requests will be unnecessary. It sounds like this isn't a great option for you.
Long Polling - This method means you would open a request up with the server and leave the request open for a long period of time. When the server gets new information it will send a response and close the request - after which the client will immediately open up a new "long poll" request. This eliminates some of the unnecessary requests with regular polling, but it is a bit of a hack as HTTP was meant for a reasonably short request response cycle. Some PaaS providers only allow a 30 second window for this to occur for example.
Web Sockets - This is somewhat harder to setup, but ultimately is the best solution for real time server to client (and vice versa) communication. A socket connection is opened between the server and client and data is passed back and forth whenever either party would like to do so. Javascript has full web socket support now and Flask has some extensions that can help you get this working. There are even great third party managed solutions like Pusher.com that can give you a working concept very quickly.
I notice an instant messenger using javascript/http/xmlhttprequest rather than tcp/websocket to communicate.
such as http://w.qq.com/login.html
I monitored its communication way in chrome developer tool.
All are http requests. One request to server every minute.
The thing I confused is that if I send a message to the http client, it receives the message immediately.
As I know http client can not get message from others, it has to send request and get response.
Is there any way to make http client to get message from others without using tcp/socket or sending request and geting response?
Your comment welcome
I don't get all this asian hieroglyphs, but they probably use long-polling: client asks server for new data and server holds answer (don't send anything, and don't close connection) while data is not ready (new message came) or until huge timeout expired. As soon as connection closed, client process response and sends next long poll request. The more common term for "permanent" connect via http called Comet. As you can see, Comet can be implemented via many techniques. As for me, the most modern is ajax streaming. It requires modern browser of course, but worth it. It's not so hard to implement streaming by yourself, but I believe there are few js libs which do the job for you.
Upd:
Here is pretty good explanation with code source
and
here is one of many questions about streaming on SO (the answer in the bottom is most interesting I guess)
I want to create a web application that displays data from a public api. I will use d3 (a javascript data-visualization library). I want to retrieve data from the api every ten minutes, and update my page (say it is traffic, or something). I have not built many web applications, how do I get the updates?
Should the js on the client side use a timer to request updates from the server side of my application (perhaps the application is written in Rails or node.js). The server then makes the api call and sends a response asynchronously? Is this called a socket? I have read that HTML5 provides sockets.
Or, perhaps an AJAX request?
Or, does the server side of my application create a timer, make the api call, and then "push" updates to the view. This seems wrong to me, there could be other views in this application, and the server shouldn't have to keep track of which view is active.
Is there a standard pattern for this type of web application? Any examples or tutorials greatly appreciated.
An AJAX request (XMLHttpRequest) is probably the way to go.
I have a very simple example of an XMLHttpRequest (with Java as the backend) here: https://stackoverflow.com/a/18028943/1468130
You could recreate a backend to receive HTTP GET requests in any other server-side language. Just echo back whatever data you retrieved, and xmlhttp.onload() will catch it.
Depending on how complex your data is, you may want to find a JSON library for your server-side language of choice, and serialize your data to JSON before echoing it back to your JS. Then you can use JavaScript's JSON.parse() method to convert your server data to an object that can easily be used by the client script.
If you are using jQuery, it handles AJAX very smoothly, and using $.ajax() would probably be easier than plain-old XMLHttpRequest.
http://api.jquery.com/jQuery.ajax/
(There are examples throughout this page, mostly-concentrated at the bottom.)
It really annoys me how complicated so many of the AJAX tutorials are. At least with jQuery, it's pretty easy.
Basically, you just need to ask a script for something (initiate the request, send url parameters), and wait for the script to give you something back (trigger your onload() or jqxhr.done() functions, supplying those functions with a data parameter).
For your other questions:
Use JavaScript's setTimeout() or setInterval() to initiate an AJAX request every 600000 milliseconds. In the request's onload callback, handle your data and update the page appropriately.
The response will be asynchronous.
This isn't a socket.
"Pushing" probably isn't the way to go in this case.
If I understand correctly and this API is external, then your problem can be divided into two separate sub-problems:
1) Updating data at the server. Server should download data once per N minutes. So, it should not be connected to customers' AJAX calls. If two customers will come to the website at the same time, your server will make two API call, what is not correct.
Actually, you should create a CRON job at the server that will call API and store its' result at the server. In this case your server will always make one call at a time and have quite a fresh information cached.
2) Updating data at clients. If data at customers' browsers should be updated without refreshing the page, then you should use some sort of Ajax. It can make a request to your server once per X minutes to get a fresh data or use so-called long-polling.
I think the most effective way to implement real time Web application is to use Web socket to push changes from the server rather than polling from the client side. This way users can see changes instantaneously once server notify that there is new data available. You can read more on the similar post.
I have tried using nodejs package called socket.io to make a real time virtual classroom. It works quite well for me.
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.