Is polling the way to go for live chat on web? - asp.net

I'm trying to implement a custom live chat program on the web, but I'm not sure how to handle the real-time (or near real-time) updates for users. Would it make more sense to send Ajax requests from the client side every second or so, polling the database for new comments?
Is there a way to somehow broadcast from the database each time a comment is added? If this is possible how would that work? I'm using Sql Server 2008 with Asp.net (c#).
Thanks!

Use long polling/server side push/comet:
http://en.wikipedia.org/wiki/Comet_(programming))
Also see:
http://en.wikipedia.org/wiki/Push_technology
I think when you use long polling you'll also want your web server to provide some support in the form of non-blocking io for requests, so that you aren't holding a thread per connection.

You could have each client poll the server, and at the server side keep the connection open without responding.
As soon there is a message detected at server side, this data is returned through the already open connection. On receipt, your client immediately issues a new request.
There's some complexity as you need to keep track server side which connections is associated with which session, and which should be responded upon to prevent timeouts.
I never actually did this but this should be the most resource efficient way.

Nope. use queuing systems like RabiitMq or ActiveMQ. Check mongoDB too.
A queuing system will give u a publish - subscribe facilities.

Related

signalr managing connections in external datastore

we are looking for a way to have a background process to push out messages to the connected clients.
The approach we are taking is that whenever a new connection is established (OnConnected) we stored the connectionId alone with some request metadata (for later filtering) in our mongo db. And when an event happened (triggered from client or backend process), a workerrole (another background process) will listen to those events (via messaging or whatever) then based on the event detail it will filter the connected client using the metadata captured.
The approach seems to be ok, but we have a problem when
signalr server goes down
before the server comes backup, the client disconnects (close browser or whatever)
signalr server goes back up
we are left with connections in the mongodb which we dont know their connection status
i am wondering if there is a better way to do this, the goal is to be able to target specific connected client to push message to from a backend service (worker role)
by the way, we are using scaleout option with service bus backplane
The following guide on Mapping SignalR Users to Connections goes over several options you have for managing connections.
The approach you are currently taking falls under the "Permanent, external storage" option.
If you want/need to stick with that option, you could add some sort of cleanup procedure that periodically removes connections from your database that have been inactive for longer than a specified time. Of course, you can also proactively remove old entries when a client with matching metadata reconnects with a new connectionId.
I think the better alternative is to use a IUserIdProvider or (single-user?) groups assuming your filtering requirements aren't too complex. Using either of these options should make it unnecessary to store connectionIds in your database. These options also make it fairly easy to send messages to multiple devices/tabs that a single user could have open simultaneously.

Why HTTP was designed to be a pull protocol?

I was watching many presentations about Html 5 WebSockets , where server can initialize connection with client and push the data without the request from the client.
We don't need Polling etc.
And , I am curious , why Http was designed as a "pull" and not full duplex protocol in the first place ? What where the reasons behind that kind of decision ?
Because when http was first designed it was meant to be used to retrieve documents from a server. And the easiest way to do is when the client asks the server for a document and gets it delivered as response (or an error in case it does not exist). When you have push protocol that means the server would need to keep client connections around for potentially a long time creating more resource management problems - remember we are talking about early 1990s here.
Http was designed for simply retrieving hypertext documents from a server. There were no reasons to push anything to the client when the pages were just pure, static html without scripting capabilities.
Since there was no need at the time for pushing things back to the client, the protocol was kept simple.
HTTP is mainly a pull protocol—someone loads information on a Web server and
users use HTTP to pull the information from the server at their convenience. In particular,
the TCP connection is initiated by the machine that wants to receive the file.

Updating data in a client application, how to avoid polling?

I have a desktop client application that is talking to a server application through a REST API using simple HTTP posts. I currently have the client polling every X minutes, but I would like the data to be refreshed more frequently. Is it possible to have the server notify the client of any new data, or is that outside the scope of what an HTTP server is meant to do? Any thoughts on the best way to approach this would be much appreciated. Thanks!
You may want to check the accepted answer to the following Stack Overflow post, which describes with a very basic example how to implement Long Polling using php on the server-side:
Simple “Long Polling” example code
When using Long Polling, your client application starts a request to the HTTP server, with an infinite timeout (or a very long one). Now as soon as new data is available, the server will find an active connection ready, so it can push the data immediately. In traditional polling, you would have to wait until the application initiates a new poll, plus the network latency to reach the server before new data is sent.
Then when the data is sent, the connection is closed, but your application should open a new one immediately in order to have a constantly open connection to the server. Actually there will be a very small gap where there will not be an active connection, but this is often negligible in many applications.
If you hold the HTTP connection open on the server side then you can send data whenever there's an update, followed by flushing the connection to actually send the data. This may cause issues with the TCP/IP stack if tens of thousands of connections are required though.

How do I create a chat server that is not driven by polling?

I have created a simple chat server that is driven by client polling. Clients send requests for data every few seconds, and get handed any new messages as well as information about whether their peer is still connected.
Since the client is running on a mobile platform (iPhone), I've been looking for ways of getting rid of the polling, which quickly drains the battery. I've read that it's possible to keep an http connection open indefinitely, but haven't understood how to utilize this technique in practice. I'm also wondering whether such connections are stable enough to use in a mobile setting.
The ideal scenario would be that the server only sends data to clients when an event that affects them has occurred (such as a peer posting a message or going off line).
Is it advisable to try to accomplish this over http, or would I have to write my own protocol over tcp? How hard would it be to customize xmpp to my need (my chat server has some specialized features that I would have to easily implement).
How about push technology? see http://en.wikipedia.org/wiki/Comet_(programming)
I think you're describing XMPP over BOSH.
http://xmpp.org/extensions/xep-0206.html
I've used this http-binding method between a chat server and javascript client on non-mobile devices. It worked well for me.
You might like to check out this project which uses a variety of techniques including Comet. Release details are here, here's a snippet from that page
It’s my distinct pleasure to be able
to announce the first public showing
of a project that I’ve been working on
in my spare time in the last month or
two, a new Web Based IRC chat
application.
This project brings together a lot of
new technologies which had to be
developed to make this a feasible,
scalable and efficient.
Some of the underlying tools build to
make this posible that i consider
’stable enough’ are already released,
such as the php Socket Daemon library
i wrote to be able to deal with
hundreds up to many thousands of
“Comet” http connections, and an equal
amount of IRC client connections.
I just found this article myself, which describes the following technique (which I referred to in the question):
... have the client make an HTTP request
and have the server hold the request
on the queue until there is a message
to push. if the TCP/IP connection is
lost or times-out, the client will
make a new HTTP request, and the delay
will only be the round trip time for a
request/response pair . . . this model
effectively requires two TCP/IP
connections for HTTP, client to
server, though none permanent and
hence mobile friendly
I think this is nearly impossible and dangerous. The internet works stateless and connectionless meaning that the connection between client and server is always handled as unreliable. And this is not for fun.
By trying to get a stateful connection you are introducing new issues. Especially from a 3g application. What if the connection breaks? You have no control over the server and cannot push.
I think it would even be easier to send sms/text messages and have an application that handles that.

What's the best way for the server to send messages to a web client?

Links to articles would also be appreciated--I don't know the terminology to search for.
I'm looking to learn how a web application can allow for server-to-client communications. I know the web was not designed for this and that it has been something of a hurdle, and am just wondering what the state of this is, and what the best practices are.
An alternative is constant or occasional polling via ajax, but is it possible for web servers to maintain stateful connections to a web client?
Edit: Another way to ask this question is how does StackOverflow tell a page that new posts are available for it to display that little bar at the top?
StackOverflow polls the server to check if there is more data.
What you're looking for is Comet.
To get true two way communications from a browser you need to use a plugin technology like Silverlight, Flash, et al. Those plugins can create TCP connections that can establish a two way persistent connection with a server socket. Note that you can't really establish the TCP connection with the HTTP server so you'd have to create an additional server agent to do the communicating back to the browser.
Basically it's a completely differnet deployment model to what AJAX sites like Stackoverflow, Gmail etc. use. They all rely on the browser polling the server at set intervals.
Web browsers really aren't set up to handle this sort of communication. The communication is a one way street where the web server is listening on a port (typically 80 or 443) for for information to be sent to it.
I just read the link on comet, and it's interesting approach, but what has to be remembered is that it is still technically being opened by the client. The server is sending code for it to execute, but the browser is ultimately in control and determines when the server communicates with it.
With today's web browsers the server can never technically execute a message being sent to it without the help of the browser. Technically you might be able to get around that by executing some Active X control on the client machine...but I haven't tried it.
You can't, HTTP is stateless. A long time ago Netscape implemented HTTP Push but it wasn't a sucess.
I'd use polling with a web service or similar; no plugin (that is Flash, Java,Silverlight) will have rights in its sandbox to use raw sockets so it'll be a waste of time trying to implement it that way.

Resources