Web project often requires to push data to clients as fast as possible, whenever it is necessary without waiting for client request. It is perfect for website with real time communication between users, like with online communicators for example. Or document collaboration tools. Or maybe system status updates on long running calculation/tasks performed by server. In every case two way communication mechanism is ideal.
Before, following solution was used for this kind of problems:
- Flash Sockets connections
(http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/Socket.html) - Ajax long polling
(https://gist.github.com/jasdeepkhalsa/4353139) - Server Sent Events…
(http://en.wikipedia.org/wiki/Server-sent_events) - …or just Forever Frame in IE because… because it is IE 🙂
(http://cometdaily.com/2007/11/05/the-forever-frame-technique/)
But now we have something better: WebSocket. Standard is implemented for some time now in modern browsers. It was released in 2011, which is even better because with changes and upgrades with have more secure and mature protocol.</>
Few remarks:
Comparison was made few months ago and can be outdated a bit, but I think that is still useful if anyone will be looking for good WebSocket library.
Only libraries published as NuGet packages was taken into account, beside one, SuperWebSocket which I found using NuGet repository, but it was needed to download from web page anyway.
Maybe if I will find time, I will update this article with new libraries or new version of already tested libraries.
-
-
Fleck
https://github.com/statianzo/Fleck
I did found it really simple to install and use. I did not have any problems with library, documentation, examples etc. Just add package, copy some samples and run project. Simple.
But with simplicity there is a price: it is not very powerful nor configurable solution.
private static void Main(string[] args) { var server = new WebSocketServer("ws://localhost:8181"); server.Start(socket => { socket.OnOpen = () => OnOpen(socket); socket.OnClose = () => OnClose(socket); socket.OnMessage = m => OnMessage(socket, m); }); }
I would use this library for quick or simple project. If you do no need complex data structure to be send through WebSocket, command-like messages, many servers or fallback when you client do not have WebSocket support, this may be library for you.
Advantages:
- Simple
- No dependencies
Disadavantages:
- Not very configurable
- No fallback in case your browser do not support WebSocket
-
-
-
SignalR
It is library from Micrsoft which I personally treat as advantage. It has integration with existing framework, ASP.NET and good abstraction for both: client and server code. It means that you do not have to know much about a protocol which is good. And it is able to fallback gracefully to other communication mechanism whenever your client cannot use WebSocket. Also it is possible to accomplish something that is called Remote Procedure Call, from server to client.
It can broad cast data to all clients or send message to only one. And scale to really great number of simultaneous connections. And is open source!
Sounds really great, right? Yeah… except it needs IIS8 on Windows Server 2012 (or Windows 8 for that matter, but you would not host any really big project on that system, right?). For me it is one of cool features of ‘Microsoft-new-server-OS-which-you-should-buy’. It is not bad if you want to develop enterprise project, but for small projects this library is too expensive even if it is open source.
Of course this requirements are actually needed if you want WebSocket communication. But this article is about WebSocket communication, so I count this as really big disadvantage.
public class MyHub1 : Hub { public void Send(string name, string message) { // Call the broadcastMessage method to update clients. Clients.All.broadcastMessage(name, message); } }
$(function () { var chat = $.connection.myHub1; chat.client.broadcastMessage = function (name, message) { //... }; $.connection.hub.start().done(function () { $('#sendmessage').click(function () { chat.server.send('message'); }); }); });
Advantages:
- Good abstraction
- Good integration with IIS and ASP.NET
- Many fallbacks
- Open source
- Microsoft library
- Scallable
Disadvantages:
- IIS 8 required…
- … which needs very expensive server OS, Windows Server 2012
-
AlchemyWebSocket
This one do not really comes to mind when I recall WebSocket libraries. There is nothing wrong with this one really. It can be placed right behind Fleck. It is also really simple, easy to use, easy to install (Nuget package available) and has documentation with good examples.
It has server part and client part code built-in. It is also scalable.
static void Main(string[] args) { // instantiate a new server - acceptable port and IP range, // and set up your methods. var aServer = new WebSocketServer(81, IPAddress.Any) { OnReceive = OnReceive, OnSend = OnSend, OnConnect = OnConnect, OnConnected = OnConnected, OnDisconnect = OnDisconnect, TimeOut = new TimeSpan(0, 5, 0) }; aServer.Start(); string consoleReadLine; do { consoleReadLine = Console.ReadLine(); sockets.ForEach(s => s.Send(consoleReadLine)); } while (consoleReadLine != "exit"); }
But it also have some awkwardness, that I cannot shake off. For example there is no simple event method “OnReceive” with just string, with actual message that was sent from client. You have to do it yourself. Yes, you have to call only .ToString() to get actual message, but whole point of using a library is to not force yourself to thing about how communication protocol is implemented.
private static void OnReceive(UserContext context) { Console.WriteLine("Client " + context.ClientAddress.ToString() + " sended: " + context.DataFrame.ToString()); }
WebSocket server initialization method takes first port and then IP setting. I always thinks, in terms of address as IP and THEN port, if port is necessary. Or timeout setting: why there is timeout anyway? I can understand that it may be sometimes useful, but as a feature not as one of primary settings. But those are details really.
For me this force your code to abstract it away, with another layer of code, which should be done by this library in the first place.
Anyway you can try it out, compare performance to Fleck, and decide which would be better for your simple project.
Advantages:
- Simple
- No dependencies
- Good documentation
Disadvantages:
- A bit awkward and little more complicated from Fleck
- No fallback
-
-
-
XSockets
This one seemed really promising. I really tried and spend much more time, trying to make it work than on other libraries (even with performance tests etc). But I had no luck unfortunately. Really, anything I can think of which can be wrong with library is wrong with this one. Bad documentation which differs from code. Which one is outdated? Code or documentation? It is not easy to install and get it running. In fact this library has examples that I had hard time to build and run. Or examples that you could say, shows more about MVC framework then about XSockets library itself. I tried to run this inside ASP.NET project, MVC and WinService. Sadly none of them worked.
I really hoped for this one but eventually give up in favor of better (read any other) library. Seriously, why use library that is hard to even start simple project? You can predict more issues to come while actually using it inside a project. I recommend to stay away from this project.
public static class XSocketsBootstrap { private static IXBaseServerContainer wss; public static void Start() { wss = XSockets.Plugin.Framework.Composable.GetExport(); wss.StartServers(); } }
Advantages:
- Seems powerful
- Should have good JavaScript integration
Disadvantages:
- Complicated and hard
- Complicated to configure and run inside of WebForms, MVC and WinService
- Differences between code and documentation
- Outdated documentation and examples
-
-
-
Microsoft.WebSocket
http://msdn.microsoft.com/en-us/hh969243.aspx
Another library from Microsoft. And it requires IIS 8 too, so I did not have means to test it. Examples are really low level, so it force you to deal with buffers and streams instead of strings. In some cases this can be good, but mostly there is no point. If you have IIS 8 on server why bother with this library if you can use SignalR, which will take care most of the stuff for you.
I think this is more of proof-of-concept then usable library.
int count = receiveResult.Count; while (receiveResult.EndOfMessage == false) { if (count >= maxMessageSize) { string closeMessage = string.Format("Maximum message size: {0} bytes.", maxMessageSize); await socket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None); return; } receiveResult = await socket.ReceiveAsync(new ArraySegment(receiveBuffer, count, maxMessageSize - count), CancellationToken.None); count += receiveResult.Count; } var receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count); var echoString = "You said " + receivedString; ArraySegment outputBuffer = new ArraySegment(Encoding.UTF8.GetBytes(echoString)); await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
-
-
SuperWebsocket
http://superwebsocket.codeplex.com/
Last but not least is SuperWebsocket. I was a bit skeptical about this one (if I remember correctly this is only one package that I somehow found through NuGet website but is not available as a package). It may seems a little complicated, but in fact it is very easy. Examples supported by documentation takes you step by step from simplest WebSocket servers, to more complicated ones, with command requests, JSON, multiple servers instances, .config file configuration and more.
This library maybe do not have all cool features that other does, but it does not matter because it is very configurable and easy to make it do what you want to. It can work in ASP.NET, as console application, and windows service. Documentation however recommends running server as system service. I from my experience recommend not running it inside web application because of slowness of such solution (very bad performance, about fifty times slower than console app). From other hand standalone application with server, requires to run .exe that is not strictly part of library, but part of SuperSocket project (on which SuperWebSocket is based). This force you to do a little ‘magic’ to start server with debug session, or to enable debug at all. When you run server as application which is not strictly part of solution, there is also issue with forcing server to use latest version of assemblies from other projects.
In return you get well known solution for flexible WebSocket.
It is also open source so you can change something if you want.
From the other hand, as a disadvantage you can count lack of JavaScript client for this server (but there is C# client). Also this one has third party dependencies.
After working with this library for few months I do not know about any major issues.
Advantages:
- Nice fetueres and very configurable
- Great examples
- Example (with documentation of recommended setup)
- Can work as WinService and inside ASP.NET and console app
- Good performance
Disadvantages:
- No fallback communication
- Dependencies
Summary:
For complicated solutions/projects I recommend use of SuperWebSocket which is stable and very configurable library. For simple and fast projects I would choose Fleck, but I would give up both for SignalR if have means to use latest Windows Server as machine for tests and production.
Projects:
Test projects I was using to compare libraries you can find here: