.NET 的 WebSocket 开发包比较

Web项目经常须要将数据尽量快地推送给客户,必要时无需等待客户端请求。对于与用户之间进行实时通讯的网站,例如在线交流或文档协做工具,或者在长期运行的计算/执行任务的服务器上更新系统状态,等等这些时候,采用双向沟通机制是理想的。   之前,这类问题通常使用下面的解决方案: • 使用 Flash 中的 Socket 链接(http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/Socket.html) • Ajax 长轮询(https://gist.github.com/jasdeepkhalsa/4353139) • 服务器发送事件... (http://en.wikipedia.org/wiki/Server-sent_events) • ...或者就用 IE 中经典的 Frame 技术(http://cometdaily.com/2007/11/05/the-forever-frame-technique/)   但如今咱们有了更好的选择:WebSocket。它的标准在2011年发布,在现代浏览器上已实施了一段时间。它更好的缘由是使用更安全和更成熟的协议,带来了改进和升级。   略注:   这份比较是几个月前作的,可能不够及时,但若是有人要找好的WebSocket库,我认为这对他仍然是有用的。   本比较只针对以 NuGet 包形式发布的库, SuperWebSocket 虽然使用 NuGet 的 repository,但须要从网页中下载。   也许等我抽出空来,我会使用新的库或已测试的库的新版本进行比较而后更新这篇文章。  Fleck   https://github.com/statianzo/Fleck   我发现这个库真的是简单易用,对于库、文档、例子等都是,只要添加库,复制几行例子里的代码,而后运行——就这么简单。   可是简单是有代价的:其功能并不强大,且可配置的地方太少。 1 2 3 4 5 6 7 8 9 10 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); }); }   对于简单快速的项目我会用它,若是你不须要用WebSocket发送太复杂的数据结构、命令同样的消息、或在客户端无WebSocket支持时的备选方式,这就是你要的了。   优势: • 简单 • 无依赖项   缺点: • 可配置项少 • 客户端浏览器不支持WebSocket时就没戏了  SignalR   http://www.asp.net/signalr   微软出品是我认为这个库最大的优势了。它已经和现有的ASP.NET框架作了集成,对服务器端和客户端代码都作了很好的抽象类, 这意味着你不须要太深刻了解协议的东西。而后它还能够很聪明地在客户端浏览器不支持WebSocket时自动使用别的通讯机制。它还能够完成一些叫远程过程调用(RPC)的东西,从服务器到客户端。   它能广播消息到全部客户端,也能单独发给指定用户。对大量并发链接的处理也很优秀。还有——它是开源的!   听起来很棒是不?可是...它须要IIS8或者说Windows Server 2012(Windows8也行,不过相信你不会在win8上面跑大项目的)。对我来讲,这就是“微软新一代值得买的操做系统”的超酷特性。若是开发企业项目的话是不错的,但对小项目来讲,为了这个开源的库买操做系统——太贵了。   固然这些环境是WebSocket必需要求的. 这篇文章就是讲WebSocket通信的,因此我把这个算成大缺点。 1 2 3 4 5 6 7 8 public class MyHub1 : Hub { public void Send(string name, string message) { // Call the broadcastMessage method to update clients. Clients.All.broadcastMessage(name, message); } } 1 2 3 4 5 6 7 8 9 10 11 $(function () { var chat = $.connection.myHub1; chat.client.broadcastMessage = function (name, message) { //... }; $.connection.hub.start().done(function () { $('#sendmessage').click(function () { chat.server.send('message'); }); }); });   优势: • 很是好的抽象 • 与IIS和ASP.NET紧密集成 • 不少候选方式 • 开源 • 微软官方库 • 可扩展性好   缺点: • 须要IIS8… • … 也就是Windows Server 2012太贵了  AlchemyWebSocket   http://alchemywebsockets.net/   当我想到websocket库时,这个让人难以想象。没错这是真的。它能够排在Fleck后面,它很是容易使用,容易安装(Nuget包可用),文档中含有很好的例子。   它包含服务端和客户端两部分,同时也具备可伸缩性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 static void Main(string[] args) { // 建立一个新的server - 接受端口和ip范围, // 设置方法 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"); }   可是它有一些别扭,我不能避开。例如那里没有简单的事件方法"OnReceive",仅仅只有string,事实上消息在客户端被发送了。你必须你本身完成。是的,你必须调用,并且只能调用 .ToString()来获得真实的消息,但使用库的目的是为了避免要强迫本身实现通讯协议。 1 2 3 4 private static void OnReceive(UserContext context) { Console.WriteLine("Client " + context.ClientAddress.ToString() + " sended: " + context.DataFrame.ToString()); }   WebSocket服务器初始化方法首先接收端口而后是IP设置。我一直认为,地址的表达应该是先IP而后是端口,并且只有当有必要指明端口的时候。还有超时设置:为何必须有超时呢?我能够理解这有时多是有用的,但它做为一个特性不该做为主要设置之一。固然,这只是一些细节问题。   对我来讲这迫使你一开始就得经过这个库用另外一层代码把它抽象出来。   总之你能够试试,和Fleck比较一下性能,而后决定哪一个更适合你的简单项目。   优点: • 简单 • 无依赖性 • 文档完备   缺点: • 有点笨拙,比Fleck结构更复杂 • 没有 fallback  XSockets   http://xsockets.net/   这个库看上去颇有前途。我尝试过它,而且还花了不少时间,用它工做超过其它的库(甚至用来执行测试工做等等)。可是很不幸我没有运气,任何我考虑到的错误在这个库中都是错误的,与代码不一致的糟糕文档。难道是由于代码或者文档过时了?它不容易安装和运行,事实上这个库的使用样例我很难组建和运行。Xsocket更多向咱们展现了MVC框架的样子。我尝试把它运行在ASP.NET项目里面,MVC和WinService,遗憾的是没有一个可以工做。   我真的很想用这个库,但最后我放弃了以便支持更好的库(阅读其余)。认真地说为何使用这个库是困难的,甚至一个简单的项目。你能够预测更多的问题当把它使用在项目里,我强烈建议避开这个项目。 1 2 3 4 5 6 7 8 9 public static class XSocketsBootstrap { private static IXBaseServerContainer wss; public static void Start() { wss = XSockets.Plugin.Framework.Composable.GetExport(); wss.StartServers(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33html

Advantages:git

  • Seems powerful
  • Should have good JavaScript integration

Disadvantages:github

  • 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.aspxweb

    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.windows

    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/
      最后但并非最不重要的是SuperWebsocket。我对这个有一点怀疑(若是我没记错的话,这仅仅是一个我经过NuGet网站发现的包,但又不是一个可用的包)。它彷佛有一点复杂,但实际上它是很是简单的。有文献支持的例子帮助你一步步的从最简单的WebSocket服务器,到有命令请求,JSON,多服务器实例,.config文件配置或者更多的复杂Websocket服务器。
      这个库也许没有包含全部其余库有的那些很酷的特性,可是这不要紧,由于它是高度可配置的,你能够很容易的让它实现你想要的。它能够做为控制台应用程序或者windows服务运行于ASP.NET中。文献上则建议以系统服务的形式来运行服务器。从个人经验来看,建议不要在一个web应用程序里面运行它由于这种解决方案很慢(很是糟糕的表现,比控制台应用程序大约慢50倍)。从另外一方面,独立的服务器应用程序,须要运行.exe结尾的文件,这个文件并非库的一部分,可是是SuperSocket项目的一部分(SuperWebSocket就是基于这个项目的)。这使得你须要一点技巧在调试会话中开启服务器,或者彻底启用调试。当你做为应用程序运行服务器的时候,虽然这不是解决方案的一部分,也须要确保服务器采用来自其余项目的最新版的组件。
      做为回报,你获得了关于灵活的WebSocket的众所周知的解决方案。
      它仍然是开源的因此你能够根据须要改变它。
      从另外一方面,你可能把这个服务器缺少JavaScript客户端看作是它的缺点(可是它有C#客户端)。这个服务器也有第三方的依赖关系。
      在使用这个库工做了几个月以后我没发现什么主要的问题。
      缺点和优势:
    •	无备用通讯
    •	依赖
    •	优雅的特性和高度可配置性
    •	很棒的例子
    •	例子的都有推荐设置的文档
    •	能够做为windows服务和ASP.NET模块和控制台应用程序运行
    •	好的性能表现
     总结
      对于复杂的解决方案/项目建议用SuperWebSocket,由于它是一个稳定并且高度可配置的库。对于简单和须要快速开发的项目我会选择Fleck,可是若是有办法使用最新的windows服务器来做为测试和生产机器的话,建议放弃使用这两个而选择SignalR。
    
    
    
    
相关文章
相关标签/搜索