Understanding the Real-time Web
Polling
- Clients periodically ask the server if there’s an update. For each poll, a HTTP request is made, and the server either responds with a new status or 204 No Content
Long Polling
-
Clients send HTTP request to the server. But the server will not complete the request but leave it until there’s an update. When there’s no update within a certain timeframe, the request will time out. When that happens, the client will just start the process again by issuing a new request.
-
Long Polling is more efficient than polling, but it is still using HTTP requests to ask for updates.
Server Sent Events (SSE)
-
a HTML5 feature, the server creats an HTTP connection to the client(browser) with Server Sent Events. The browser will listen for messages that will come in as a stream. The connection will remain open until it is actively closed.
-
The browser will use an object called EventSource that has an event onmessage to process incoming messages.
- Using simple HTTP
- Auto reconnects
- No support for older browsers
- Easily polyfilled
- Maximum HTTP connections issue (6 connections at most)
- Only support text messages
- One-way connection
Web Sockets
-
A standardized way to use one TCP socket through which messages can be sent from server to client and vice versa and without the latency of HTTP.
-
A TCP socket typically remains open for as long as the stream of the messages are not done.
-
SignalR will use WebSockets most of the time because its the most efficient transport.
- Full duplex messaging (client to server and vice versa)
- No 6 connections limit
- For most browsers, the connection limit for web sockets is about 50 connections
- Multi data type support (text, binary)
- TCP socket upgrade (Regular HTTP request uses a TCP socket as well)
-
The WebSockets standards uses a handshake mechanism to upgrade an existing socket used for HTTP traffic to a WebSocket. After that, messages can travel through the socket until the socket is actively closed. When closing, a reason for closing is communicated.
-
Every WebScoket starts its life as a simple HTTP socket, A GET HTTP call is made to the server, requesting an upgrade of the socket. If the server agrees, the socket becomes a WebSocket from that point onwards.
SignalR
- SignalR is an open source framework that wraps the complexity of real-time web transports. You don’t need to worry about the lower level transports like long polling, Server Sent Event or WebSockets.
Transports
- WebSockets, Server Sent Events, Long Polling
- Requires client and server that supports transport
- Fallback mechanism (if browser doesn’t support WebSocket, then use SSE instead, etc…)
Remote Procedure Call (RPC)
- Server can call a function in the Client and vice versa
Hub
- A hub is a server-side class that sends messages to and receives messages from clients by utilizing RPC.
- A hub protocol is a format used to serialize parameters to and deserialize parameters from
Differences with Classic SignalR
- Simplified connection model
- Single hub per connection
- Async
- Binary and custom protocols
- No jQuery dependency for JavaScript client
- Sticky session required
Scaling Out
- Running on muiltiple servers
- Load Balancer picks server
- Problem with non-WebSockets transport, it could send the first request to the first server, then send the second request to the second server, who doesn’t know anything about the context of the message.
- We could solve this problem by using sticky sessions.
- As part of the response of the first request, the load balancer sets a cookie in the browser, indicating the server that was used. On subsequent request, the load balancer then reads the cookie and assigns the request to the same server. (IIS using Application Request Routing Affinity (ARR Affinity))
-
Another problem, let’s say a user is working on a web document using Office 365, and she invites others to join her, the other might end up at another server. When user 1 on the server changes the document, a message has to be sent to the others, but server 1 doesn’t know about users that are connected to hubs in other servers.
-
To solve this, the servers need a way to share data. This can be done using a Database, but a faster alternative would be to use a Redis cache.