I created my own chat webserver in python and wanted to know instead of AJAX making a call to the server every second (JS below). I can modify my server so when ever it updates the chat.html file it pushes it out to all the clients. Is there a way using javascript to have it listen for any received data rather then polling?
<script>
// Request the AJAX update the chat window every second
setInterval(function(){loadChat()},1000);
function loadChat()
{
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("chatWindow").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","chat.html",true);
xmlhttp.send(null);
}
}
</script>
Yes, there certainly is. There are (at least) four techniques you can use:
WebSockets. This is the most obvious solution. It allows you to send and receive messages on-demand without need for polling. It may, however, be somewhat more difficult to implement on the server side, as it is not plain HTTP. Also, old browsers don't support WebSockets.
Server-Sent Events. This is less desirable, but will still work for you. With it, you can receive messages from the server without polling. It is also easier to implement on the server as it's just plain HTTP except that the connection doesn't close. It, too, is not supported in some older web browsers, but it's more supported than WebSockets and is pretty easy to shim.
COMET. This is basically an improvement of the thing below. Basically, you have an iframe that's hidden offscreen. Whenever an event comes in, you send (and flush!) a script tag, but don't close the connection. After a timeout, close the connection. Then refresh the iframe. This is also pretty easy to implement, is plain HTTP, and needs no special browser support. However, browser timeouts vary and this is somewhat inelegant.
Keeping the connection open until an event comes. This is probably the least desirable. Simply don't send a response until an event comes in. When an event comes in or a timeout occurs, send the response. When the client receives the response, reconnect. This is also somewhat inelegant but it works.
What you are talking about is pushing from the server to the client which is comet you can use such way
But this can be done perfectly with node.js and WebSockets in HTML5 but it's not supported in all browsers check this out
And you can make another thing
Send a request from your JS and make it alive for 1 minute and make an infinite loop that sleeps for some seconds and if it found anything while that return it to the client else make a new request this technique is called HeartBeat
I hope this can help
Simply, in most cases you will not be able to.. However, you can use HTML5 Websockets, though they are commonly unsupported.
SockJS, uses a variety of methods to do callbacks in JavaScript, one of which is the blocking query, another WebSockets. I would highly recommend it if you are trying to do this sort of thing.
You can do this using websockets. Unfortunately not all browsers currently support them.
More info on websockets here.
Related
I'm gonna develop a framework for comet programming, and I can't use Web Sockets, or Server-Sent Events (because browser support really sucks). So, I need to keep the HTTP connection alive, and send chunked data back to the client.
However, problems show themselves as you get into the work:
Using XMLHttpRequest is not possible, due to the fact that IE doesn't give you xhr.responseText while the xhr.readyState is 3.
A hidden iframe can't be useful, because browser shows the loader while I send data back to the client.
I tried to send a JavaScript file back to the client, sending function execution commands each time, but browsers won't execute JavaScript till it's completely loaded.
However, when I look at Lightstreamer demo page, I see that it sends a JavaScript file back to the client little by little and in each step, it sends a call to the function and that function simply gets executed (I can't do this part). It seems that Lightstreamer uses AJAX, since the request simply shows up in Firebug's console tab, but it works like a charm in IE too.
I tried to use every HTTP header field they've set on their request, and no result. I also tried to use HTTP Post instead of HTTP Get, but still got no result.
I've read almost over 20 articles on how to implement comet, but none of'em appear to solve problems I have:
How to make it cross-browser?
How to get notified when new data is arrived from server (what event should I hook into)?
How to make my page appear as completely loaded to the user (how to implement it, so that browser doesn't show loading activity)?
Can anyone please help? I think there should be a very little tip or trick that I don't know here to glue all the concepts together. Does anyone know what lightstreamer do to overcome these problems?
SockJS author here.
How to make it cross-browser?
This is hard, expect to spend a few months on getting streaming transports on opera and IE.
How to get notified when new data is arrived from server (what event should I hook into)?
There are various techniques, depending on a particular browser. For a good intro take a look at different fallback protocols supported by Socket.IO and SockJS.
How to make my page appear as completely loaded to the user (how to implement it, so that browser doesn't show loading activity)?
Again, there are browser-specific tricks. One is to delay loading AJAX after onload event. Other is to bind-and-unbind an iframe from DOM. ETC. If you still feel interested read SockJS or Socket.io code.
Can anyone please help? I think there should be a very little tip or trick that I don't know here to glue all the concepts together. Does anyone know what lightstreamer do to overcome these problems?
Basically, unless you have a very strong reason to, don't reinvent the wheel. Use SockJS, Socket.io, faye, or any other of dozens projects that do solve this problem already.
The methods you want is the streaming.
How to make it cross-browser?
Considering most browsers, there is no consistent way. You have to choose a proper transport according to the browser. Even worse, you have to rely on the browser sniffing to recognize which browser is being used, and the feature detection counts for nothing about this. You can use XDomainRequest for IE8+, XMLHttpRequest for non-IE and Iframe for IE 6+. Avoid iframe transport if possible.
How to get notified when new data is arrived from server (what event should I hook into)?
This varies according to the transport being used. For example, XDomainRequest fires progress event, XMLHttpRequest fires readystatechange event when chunk is arrived except Opera and IE.
How to make my page appear as completely loaded to the user (how to implement it, so that browser doesn't show loading activity)?
I don't know this issue with iframe, but still occurs in WebKit based browsers such as Chrome and Safari with XMLHttpRequest. The only way to avoid this is to connect after the onload event of window, but, in case of Safari, this does not work.
There are some issues you have to consider besides the above questions.
Event-driven server - The server should be able to process asynchronously.
Transport requirements - The server behaves differently for required transport.
Stream format - If the server is going to send big message or multiple messages in a single chunk, a single chunk does not mean a single data. It could be fragment of a single data or concatenation of multiple data. To recognize what is data, the response should be formatted.
Error handling - Iframe transport does not provide any evidence for disconnection.
...
Last but not least, to implement streaming is pretty tiresome than it looks unlike with long polling. I recommend you use solid framework for doing that such as socketio, sockjs and jquery socket which I've created and managed.
Good luck.
but browsers won't execute JavaScript till it's completely loaded.
Have you tried sending back code wrapped in <script> tags? For example, instead of:
<script type="text/javascript">
f(...data1...);
f(...data2...);
try
<script type="text/javascript">f(...data1...);</script>
<script type="text/javascript">f(...data2...);</script>
The best option in your case would be to use JSONP + Long Pulling on server side. You just have to remember to reconnect any time connection drops (times out) or you receive response.
Example code in jquery:
function myJSONP(){
$.getScript(url, {
success: function(){
myJSONP(); //re-connect
},
failure: function(){
myJSONP(); //re-connect
}
})
}
Obviously your response from server has to be javascript code that will call on of your global functions.
Alternatively you can use some jquery JSONP plugin.
Or take a look on this project http://www.meteor.com/ (really cool, but didn't try it)
I am looking at facebook news feed/ticker right now and I am wondering what technology/architecture it uses to pull in data asynchronously when any of my connections make an update. One possibility that I can think of is a javascript setInterval on a function that aggressively polls the server for new data.
I wonder how efficient that is.
Another possible technology that I can think of is something like Comet/NodeJS architecture that pings the client when there is an update on the server. I am not too familiar with this technology.
If I wanted to create something similar to this. What should I be looking into? Is the first approach the preferred way to do this? What technologies are available out there that will allow me to do this?
There are several technologies to achieve this:
polling: the app makes a request every x milliseconds to check for updates
long polling: the app makes a request to the server, but the server only responds when it has new data available (usually if no new data is available in X seconds, an empty response is sent or the connection is killed)
forever frame: a hidden iframe is opened in the page and the request is made for a doc that relies on HTTP 1.1 chunked encoding
XHR streaming: allows successive messages to be sent from the server without requiring a new HTTP request after each response
WebSockets: this is the best option, it keeps the connection alive at all time
Flash WebSockets: if WS are not natively supported by the browser, then you can include a Flash script to enhance that functionality
Usually people use Flash WebSockets or long-polling when WebSockets (the most efficient transport) is not available in the browser.
A perfect example on how to combine many transport techniques and abstract them away is Socket.IO.
Additional resources:
http://en.wikipedia.org/wiki/Push_technology
http://en.wikipedia.org/wiki/Comet_(programming))
http://www.leggetter.co.uk/2011/08/25/what-came-before-websockets.html
Server polling with JavaScript
Is there a difference between long-polling and using Comet
http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery
Video discussing different techniques: http://vimeo.com/27771528
The book Even Faster Websites has a full chapter (ch. 8) dedicated to 'Scaling with Comet'.
I could be wrong, but I think that Facebook relies on a "long polling" technique that keeps an http connection open to a server for a fixed amount of time. The data sent from the server triggers an event client side that is acted upon at that time. I would imagine that they use this technique to support the older browsers that do not have websocket support built in.
I, personally, have been working on an application with similar requirements and have opted to use a combination of node.js and socket.io. The socket.io module uses a variety of polling solutions and automatically chooses the best one based on what is available on the client.
Maybe you may have a look to Goliath (non-blocking IO server written in Ruby) : http://postrank-labs.github.com/goliath/
In asp.net, How can i trigger client side jquery event from server. I want to implement it in my chat section... current the chat seems to work fine... but it has one problem... i have to send a request every 5 seconds from client's browser to the his chat history.. which i feel is not a good idea...
can anyone provide any solution for my problem
By default you need to do it with polling from the clients browser. That's how ajax works out of the box. There's a technique called Comet which is a push model.
You can try to use a jQuery plugin like this: http://plugins.jquery.com/project/jQuery-Comet-Push-API.
In the (near) future you could make use of websockets as well in HTML5. Here's information taken from http://channel9.msdn.com/Events/MIX/MIX11/HTM10.
WebSockets, an emerging specification
being standardized by W3C and IETF,
will enable web browsers as well as
client applications to open a
bi-directional, full-duplex
communication channel with a remote
host.
Be sure to check out that MIX11 video!
Although, I am not that skilled in ASP.Net, this problem can be solved in another way.
Have the server return the name of function you need to execute, then call it in the callback function?
Kinda like this (It is just a typo but)
$.post("yourpage.aspx",
{
d1: "v1"
},
function(data) {
//now the data will hold the name of the function
window[data]();
}
);
Now you can wrap the above code, in the another function, and set up a timer, to check for the response regularly, and execute the function if a condition is matched.
P.S. I have skipped the part, where the scripts check if the condition is matched.
You are doing the best that you can do without getting into something like HTML5 WebSockets which are not really ready for regular usage yet.
Two options:
(conservative option) Accept that you will be polling the server and optimize the way you do the polling to keep the impact low.
(edgy option) Try out some of the new libraries that emulate Websockets.
Welcome to the world of HTTP.
Thats how the browsers work. Client sends a request to the Server and Server responds. There is no other way (for now) to go the other way. It's simple and that's one of the reasons HTTP protocol was so popular.
But now things are changing and HTML5 support web sockets. If you developing for a HTML5 supporting device (latest versions of all browsers + iPhone/iPad support sockets) then websockets is the way to go.
On the other side, you can go with Comet polling (as mentioned by XIII). Basically it client sends a request to the server and waits until server has anything to respond to. I am not too sure what is a good way of implementing it in ASP.NET (as I think there is a limit of concurrent connections) but it's a pretty useful technique in Nodejs.
I'm just wondering if there is a way to have a server push information to a JavaScript function. Essentially I have a Dashboard-type page that has a javaScript function to get updates from the server and update the dashboard.
I would like my server to be able to "ping" the JS.
I don't even know how that could be possible (I'm guessing Twitter and Facebook use polling?), but I'd thought I ask.
I heard of Comet, but I don't know if that works with a plain standard IIS 7 installation? (It's a SharePoint 2010 site if that matters in any way) If I understand it correctly, Comet is essentially a constantly open connection, so it seems like it's actually the opposite of what I want (reducing # of requests and therefore load)
If you're looking for a comet server for IIS, check out WebSync; it's exactly that :)
Truly initiating a connection from the server is not possible using HTTP. Comet isn't really a single technique, but a set of different workarounds (many of which are described at the article you linked).
For information on Comet techniques with IIS, see the prior question, Comet Programming in IIS. One of the programs discussed there is WebSync.
A Comet style workaround is the most common way to get this functionality. The connection is not constantly open, but rather throttled to make calls every x seconds, then try again upon timeout. The timeout essentially means that the server didn't have anything to give to the client in the duration of the poll. You'll see that the Etherpad code used this same approach, which has been integrated into other Google products now like Google Docs and Wave.
As Samuel Neff says, "You're going to need an open connect to "push" data from the server to the client."
You can use a service like pubnub to open persistent connections from the client and support fallbacks for older browsers.
I made a small demo to show you how the front-end of this application may work. The demo shows PubNub latency over time. The source is available here.
The browser subscribes to a channel and fires a callback when a message is received.
pubnub.subscribe({
channel: 'my_channel',
message: function(m){console.log(m)}
});
In the demo the client also publishes messages. In your case you would include the PubNub IIS library.
pubnub.Subscribe<string>(channel="mychannel", DisplaySubscribeReturnMessage, DisplaySubscribeConnectStatusMessage, DisplayErrorMessage);
// NOTE: DisplaySubscribeReturnMessage, DisplaySubscribeConnectStatusMessage and DisplayErrorMessage are callback methods
You're going to need an open connect to "push" data from the server to the client. So even if you went the route of using a plugin like Flash to open a socket connection which supports two-way communications, you have an open socket connection.
Your statement "reducing # of requests and therefore load" really is problematic. You're equating number of requests with load and that is not accurate. With Comet the majority of requests are waiting on data. Therefore you can have a very high number of requests, but really a very low load on the server--it's hardly using resources besides a waiting thread from the worker thread pool.
Use Comet. Works great, is simple to implement, and does exactly what you need.
You have to do it the other way around, by having the client "pinging" the server with JS.
You can do something like:
function pollServer()
{
// Get some parameter
var param = .......
AJAXCall("page.php?param="+param, onReturn);
}
function onReturn(response)
{
// do something with response
setTimeout("pollServer()", 5000);
}
pollServer();
AJAXCall being the function you use to do an AJAX call and that calls onReturn when it gets a response.
Once it gets a response it waits in this case 5 seconds and polls the server again
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.