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
Related
I use setInterval to get my notification counter every 5 second, I thinks it's bad idea to getting those results. because if you stay on my site for a while you got a billion times of loading XHR loading.And if you use the facebook, you don't get lot of XHR.Here is my web site capture XHR:
My Code in file: notification.php:
function getnotificount(){
$.post('getnotificount.php', function(data) {
$('#notifi_count').html(data);
});
}
setInterval(function(){
getnotificount();
}, 5000);
Your code is ok. It is not 'loading more than 1 billion XHR request', it's starting (and finishing - as we can see) a request every X seconds and there's nothing wrong with that.
However it's not the best way to implement a push notification system. That would be websockets, which is a way for your client to 'listen' to messages from your server. There are frameworks for this, the most popular one (and the one that I recommend) being socket.io.
Your third and most advanced/modern solution would be implementing a service-worker-based notification system but I'm pretty sure that's way too complex and not suitable for you since you can't even understand your problem enough to describe it.
What you are doing is polling, which is making a new request to the server on a regular bases. For a http request, a TCP connection is opened, request / response are exchanged and the TCP connection closed. This is what happens every 5s in your case.
If you want a more light weight solution, have a look at websockets such as socket.io. Only one TCP connection is opened and maintained between the front and the back. This bidirectional conection enables the back to notify the front when something happens.
It is not a bad idea at all. It is called polling and it is used at many places as a means to get regularly data from the server. However, it is not the best, nor the most modern solution to do this. In fact, if your server supports WebSockets, then you should use them. You do not need to use NodeJS to use WebSockets, since WebSocket is a protocol of creating a duplex channel of communication between your server and the client. You should read about WebSockets. Also, you can use push notification, which is inferior to WebSockets in my opinion. And a hacky way is to use a forever frame.
Of course I am aware of Ajax, but the problem with Ajax is that the browser should poll the server frequently to find whether there is new data. This increases server load.
Is there any better method (even using Ajax) other than polling the server frequently?
Yes, what you're looking for is COMET http://en.wikipedia.org/wiki/Comet_(programming). Other good Google terms to search for are AJAX-push and reverse-ajax.
Yes, it's called Reverse Ajax or Comet. Comet is basically an umbrella term for different ways of opening long-lived HTTP requests in order to push data in real-time to a web browser. I'd recommend StreamHub Push Server, they have some cool demos and it's much easier to get started with than any of the other servers. Check out the Getting Started with Comet and StreamHub Tutorial for a quick intro. You can use the Community Edition which is available to download for free but is limited to 20 concurrent users. The commercial version is well worth it for the support alone plus you get SSL and Desktop .NET & Java client adapters. Help is available via the Google Group, there's a good bunch of tutorials on the net and there's a GWT Comet adapter too.
Nowadays you should use WebSockets.
This is 2011 standard that allows to initiate connections with HTTP and then upgrade them to two-directional client-server message-based communication.
You can easily initiate the connection from javascript:
var ws = new WebSocket("ws://your.domain.com/somePathIfYouNeed?args=any");
ws.onmessage = function (evt)
{
var message = evt.data;
//decode message (with JSON or something) and do the needed
};
The sever-side handling depend on your tenchnology stack.
Look into Comet (a spoof on the fact that Ajax is a cleaning agent and so is Comet) which is basically "reverse Ajax." Be aware that this requires a long-lived server connection for each user to receive notifications so be aware of the performance implications when writing your app.
http://en.wikipedia.org/wiki/Comet_(programming)
Comet is definitely what you want. Depending on your language/framework requirements, there are different server libraries available. For example, WebSync is an IIS-integrated comet server for ASP.NET/C#/IIS developers, and there are a bunch of other standalone servers as well if you need tighter integration with other languages.
I would strongly suggest to invest some time on Comet, but I dont know an actual implementation or library you could use.
For an sort of "callcenter control panel" of a web app that involved updating agent and call-queue status for a live Callcenter we developed an in-house solution that works, but is far away from a library you could use.
What we did was to implement a small service on the server that talks to the phone-system, waits for new events and maintains a photograph of the situation. This service provides a small webserver.
Our web-clients connects over HTTP to this webserver and ask for the last photo (coded in XML), displays it and then goes again, asking for the new photo. The webserver at this point can:
Return the new photo, if there is one
Block the client for some seconds (30 in our setup) waiting for some event to ocurr and change the photograph. If no event was generated at that point, it returns the same photo, only to allow the connection to stay alive and not timeout the client.
This way, when clients polls, it get a response in 0 to 30 seconds max. If a new event was already generated it gets it immediately), otherwise it blocks until new event is generated.
It's basically polling, but it somewhat smart polling to not overheat the webserver. If Comet is not your answer, I'm sure this could be implemented using the same idea but using more extensively AJAX or coding in JSON for better results. This was designed pre-AJAX era, so there are lots of room for improvement.
If someone can provide a actual lightweight implementation of this, great!
An interesting alternative to Comet is to use sockets in Flash.
Yet another, standard, way is SSE (Server-Sent Events, also known as EventSource, after the JavaScript object).
Comet was actually coined by Alex Russell from Dojo Toolkit ( http://www.dojotoolkit.org ). Here is a link to more infomration http://cometdproject.dojotoolkit.org/
There are other methods. Not sure if they are "better" in your situation. You could have a Java applet that connects to the server on page load and waits for stuff to be sent by the server. It would be a quite a bit slower on start-up, but would allow the browser to receive data from the server on an infrequent basis, without polling.
You can use a Flash/Flex application on the client with BlazeDS or LiveCycle on the server side. Data can be pushed to the client using an RTMP connection. Be aware that RTMP uses a non standard port. But you can easily fall back to polling if the port is blocked.
It's possible to achive what you're aiming at through the use of persistent http connections.
Check out the Comet article over at wikipedia, that's a good place to start.
You're not providing much info but if you're looking at building some kind of event-driven site (a'la digg spy) or something along the lines of that you'll probably be looking at implementing a hidden IFRAME that connects to a url where the connection never closes and then you'll push script-tags from the server to the client in order to perform the updates.
Might be worth checking out Meteor Server which is a web server designed for COMET. Nice demo and it also is used by twitterfall.
Once a connection is opened to the server it can be kept open and the server can Push content a long while ago I did with using multipart/x-mixed-replace but this didn't work in IE.
I think you can do clever stuff with polling that makes it work more like push by not sending content unchanged headers but leaving the connection open but I've never done this.
You could try out our Comet Component - though it's extremely experimental...!
please check this library https://github.com/SignalR/SignalR to know how to push data to clients dynamically as it becomes available
You can also look into Java Pushlets if you are using jsp pages.
Might want to look at ReverseHTTP also.
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 already tossing around a solution but as I haven't done something like this before I wanted to check what SO thought before implementation.
Basically I need to modify an existing web based application that has approximately 20 users to add push notifications. It is important that the users get the notifications at the same time (PC-A shouldn't get an alert 20 seconds before PC-B). Currently the system works off of AJAX requests, sending to the server every 20 seconds and requesting any updates and completely rebuilding the table of data each time (even if data hasn't changed). This seems really sloppy so there's two methods I've come up with.
Don't break the connection from server-client. This idea I'm tossing around involves keeping the connection between server and client active the entire time. Bandwidth isn't really an issue with any solution as this is in an internal network for only approximately 20 people. With this solution the server could push Javascript to the client whenever there's an update and modify the table of data accordingly. Again, it's very important that every connected PC receives the updates as close to the same time as possible. The main drawback to this is my experience, I've never done it before so I'm not sure how well it'd work or if it's just generally a bad idea.
Continue with the AJAX request, but only respond in intervals. A second solution I've thought of would be to allow the clients to make AJAX requests as per usual (currently every 20 seconds) but have the server only respond in 30 second intervals (eg 2:00:00 and 2:00:30 regardless of how many AJAX requests it recieves in that span of time). This would require adjusting the timeout for the AJAX request to prevent the request timing out, but it sounds okay in theory, at least to me.
This is for an internal network only, so bandwidth isn't the primary concern, more so that the notification is received as close to each other as possible. I'm open to other ideas, those are just the two that I have thought of so far.
Edit
Primarily looking for pros and cons of each approach. DashK has another interesting approach but I'm wondering if anyone has experience with any of these methods and can attest to the strengths and weaknesses of each approach, or possibly another method.
If I understand well your needs I think you should take a look to Comet
Comet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it. Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins.
The Comet approach differs from the original model of the web, in which a browser requests a complete web page at a time.
How about using an XMPP server to solve the problem?
Originally designed to be an Instant Messaging platform, XMPP is a messaging protocol that enables users in the system to exchange messages. (There's more to this - But let's keep it simple.)
Let's simplify the scenario a little bit. Imagine the following:
You're a system admin. When the system
has a problem, you need to let all the
employees, about 20 of them, know that
the system is down.
In the old days, every employee will
ask you, "Is the system up?" every
hour or so, and you'll response
passively. While this works, you are
overloaded - Not by fixing system
outage, but by 20 people asking for
system status every hour.
Now, AIM is invented! Since every
employee has access to AIM, you
thought, "Hey, how about having every
single one of them join a 'System
Status' chat room, and I'll just send
a message to the room when the system
is down (or is back)?" By doing so,
employees who are interested in
knowing system status will simply join
the 'System Status' room, and will be
notified of system status update.
Back to the problem we're trying to solve...
System admin = "System" who wants to notify the web app users.
Employees = Web app users who wants to receive notification.
System Status chat room = Still, system Status chat room
When web app user signs on to your web app, make the page automatically logs them onto the XMPP server, and join the system status chat room.
When system wants to notify the user, write code to logon to the XMPP server, join the chat room, and broadcast a message to the room.
By using XMPP, you don't have to worry about:
Setting up "Lasting connection" - Some open source XMPP server, eJabberd/OpenFire, has built-in support for BOSH, XMPP's implementation of the Comet model.
How the message is delivered
You however will need the following:
Find a Javascript library that can help you to logon to an XMPP server. (Just Google. There're a lot.)
Find a XMPP library for the server-side code. (XMPP library exists for both Java & C#. But I'm not sure what system you're using behind the scene.)
Manually provision each user on the XMPP server (Seems like you only have 20 people. That should be easy - However, if the group grows bigger, you may want to perform auto-provisioning - Which is achievable through client-side Javascript XMPP library.)
As far as long-lasting AJAX calls, this implementation is limited by the at-most-2-connection-to-the-same-domain issue. If you used up one connection for this XMPP call, you only have 1 more connection to perform other AJAX calls in the web-app. Depending on how complex your webapp is, this may or may not be desirable, since if 2 AJAX calls have already been made, any subsequent AJAX call will have to wait until one of the AJAX pipeline freed up, which may cause "slowness" on your app.
You can fix this by converting all AJAX calls into XMPP messages, and have a bot-like user on the server to listen to those messages, and response to it by, say, sending back HTML snippets/JSON objects with the data. This however might be too much for what you're trying to achieve.
Ahh. Hope this makes sense... or not. :p
See http://ajaxpatterns.org/HTTP_Streaming
It allows You to push data from the server when server wants it. Not just after the query.
You could use this technique without making large changes to the current application, and synchronize output by the time on the server.
In addition to the other two great options above, you could look at Web Workers if you know they have latest Chrome, Safari, FF, or Opera for a browser.
A Worker has the added benefit of not operating in the same thread as the rest of the page, so performance will be better. The downside is that, for security purposes, you can only send string data between the two scripts and the worker does not have window or document context. However, JSON can be represented as a string, so there's really no limit to the data.
Workers can receive data multiple times and asynchronously. You set the onmessage handler to act each time it receives something.
If you can ask every user to use a specific browser (Latest Safari or Chrome), you can try WebSockets too.