C#开源的C#实现WebSocket协议客户端和服务器websocket-sharp组件解析

 
很久没有写博客了(至少本人感觉到不短日子从没写了),不能啊,楼主也是须要生活的人呀,那段间接都在找工作怎么着的。(整天催我代码的人,还望多多谅解啊,作者会坚定不移写咱俩的种类的,依旧必要相信本身的,终究那是1个耗时耗力的工作,要求有所参加者都坚定不移的作业。)

 
上边扯淡达成后,上边进入大家后天的完好。看到那篇博客的难点,推断很多人都会问,那一个组件是或不是有个别显的无聊了,说到web通讯,很三个人都会想到ASP.NET
SignalCR-V,也许Nodejs等等,达成web的网络实时报纸发表。有关于web实时通讯的连带概念难题,在此处就不再做具体的牵线了,有趣味的能够自行百度。

  上面大家介绍一款WebSocket组件websocket-sharp的相关内容。

一.websocket-sharp组件概述

   
websocket-sharp是一个C#贯彻websocket协议客户端和服务端,websocket-sharp支持酷威FC
6455;WebSocket客户端和服务器;音信压缩扩充;安全连接;HTTP身份验证;查询字符串,初始标题和Cookie;通过HTTP代理服务器连接;.NET
Framework 3.5或更高版本(包含包容环境,如Mono)。

 
  websocket-sharp是2个单纯的零部件,websocket-sharp.dll。websocket-sharp是用MonoDevelop开发的。所以建立五个简短的措施是开辟websocket-sharp.sln并应用MonoDevelop中的任何营造配置(例如Debug)运营websocket-sharp项指标塑造。

   
上边介绍了.NET项目中添加websocket-sharp组件,即使想向Unity项目中央银行使该DLL ,则应将其添加到Unity
艾德itor中的项目标其他文件夹。在Unity的档次中,Unity
Free有一部分封锁:Webplayer的安全沙箱(Web
Player中不提供该服务器);WebGL互联网( WebGL中不可用);不适用于此类UWP;对System.IO.Compression的一定量援助(压缩增添在Windows上不可用);iOS
/ Android的.NET Socket援救(假使您的Unity早于Unity 5,则需求iOS /
Android Pro);适用于iOS / Android的.NET API 2.0匹配级别。适用于iOS /
Android的.NET API 2.0包容性级别大概须要在.NET
2.0事后修复缺少有些职能,例如System.Func<...>代理(因而作者已将其添加到该资金包中)。

二.websocket-sharp组件使用方法

    1.WebSocket客户端

using System;
using WebSocketSharp;

namespace Example
{
  public class Program
  {
    public static void Main (string[] args)
    {
      using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) {
        ws.OnMessage += (sender, e) =>
            Console.WriteLine ("Laputa says: " + e.Data);

        ws.Connect ();
        ws.Send ("BALUS");
        Console.ReadKey (true);
      }
    }
  }
}

     由地点的代码示例中,使用WebSocketWebSocket
U中华VL 创设类的新实例来三番五次。一个WebSocket.OnOpen当WebSocket连接已经创制发生的轩然大波。WebSocket.OnMessage当发生事变WebSocket收到音信。二个WebSocket.OnClose当WebSocket的连天已关闭产生的轩然大波。假如要异步连接到服务器,应该利用该WebSocket.ConnectAsync ()情势。能够选拔WebSocket.Send (string)WebSocket.Send (byte[])WebSocket.Send (System.IO.FileInfo)办法来发送数据。若是您想要异步发送数据,则应该运用该WebSocket.SendAsync艺术。假设要明了地关闭连接,应该利用该WebSocket.Close方法。

    2.WebSocket服务器

using System;
using WebSocketSharp;
using WebSocketSharp.Server;

namespace Example
{
  public class Laputa : WebSocketBehavior
  {
    protected override void OnMessage (MessageEventArgs e)
    {
      var msg = e.Data == "BALUS"
                ? "I've been balused already..."
                : "I'm not available now.";

      Send (msg);
    }
  }

  public class Program
  {
    public static void Main (string[] args)
    {
      var wssv = new WebSocketServer ("ws://dragonsnest.far");
      wssv.AddWebSocketService<Laputa> ("/Laputa");
      wssv.Start ();
      Console.ReadKey (true);
      wssv.Stop ();
    }
  }
}

 
  以通过创办继承WebSocketBehavior该类的类定义任何WebSocket服务的一坐一起。能够WebSocketServer由此采纳WebSocketServer.AddWebSocketService<TBehaviorWithNew> (string)WebSocketServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>)主意将其他WebSocket服务丰硕到服务的钦命行为和途径。wssv.Start
();运维WebSocket服务器。wssv.Stop (code, reason);停止WebSocket服务器。

    3.新闻压缩

ws.Compression = CompressionMethod.Deflate;

    4.HTTP身份验证

ws.SetCredentials ("nobita", "password", preAuth);

C#,    5.经过HTTP代理服务器连接

var ws = new WebSocket ("ws://example.com");
ws.SetProxy ("http://localhost:3128", "nobita", "password");

三.websocket-sharp组件大旨指标解析

    1.WebSocket.Send():

    private bool send (Opcode opcode, Stream stream)
    {
      lock (_forSend) {
        var src = stream;
        var compressed = false;
        var sent = false;
        try {
          if (_compression != CompressionMethod.None) {
            stream = stream.Compress (_compression);
            compressed = true;
          }
          sent = send (opcode, stream, compressed);
          if (!sent)
            error ("A send has been interrupted.", null);
        }
        catch (Exception ex) {
          _logger.Error (ex.ToString ());
          error ("An error has occurred during a send.", ex);
        }
        finally {
          if (compressed)
            stream.Dispose ();
          src.Dispose ();
        }
        return sent;
      }
    }

   
使用WebSocket连接发送钦赐的数量,该措施存在多个重载版本,并且该情势也有异步完成。该方法重回2个布尔类型的参数,表示本次音信是还是不是发送成功。该办法接受多个参数,Opcode是贰个枚举类型,表示WebSocket框架类型。该枚举类型值有Cont(等于数值0.意味着一连帧),Text(也正是数值1.意味文本框),Binary(相当于数值2.表示二进制帧),Close(约等于数值8.象征连接关闭框架),Ping(相当于数值9.代表ping帧),Pong(相当于数值10.指令pong框)。stream表示三个流对象。该办法设置了锁操作,幸免并发时出现死锁难题。可是总的来看代码中对丰裕的抓获依然有点问题,该情势是平素捕获exception卓殊,那样会导致程序捕获代码块中的全体特别,那样会潜移默化代码的平安定祥和代码的可修复性,十分捕获的最棒处理方式是将次第开始展览回复。

    2.WebSocket.CloseAsync():

public void CloseAsync (CloseStatusCode code, string reason)
    {
      string msg;
      if (!CheckParametersForClose (code, reason, _client, out msg)) {
        _logger.Error (msg);
        error ("An error has occurred in closing the connection.", null);

        return;
      }
      closeAsync ((ushort) code, reason);
    }

   
该措施以钦定的主意异步关闭WebSocket连接,该方法接受七个参数,CloseStatusCode表示关闭原因的状态码,该参数是二个枚举类型。reason代表关闭的来由。大小必须是123字节或更少。if
(!CheckParametersForClose (code, reason, _client, out
msg))检查参数关闭。

    3.WebSocket.createHandshakeRequest():

 private HttpRequest createHandshakeRequest()
        {
            var ret = HttpRequest.CreateWebSocketRequest(_uri);
            var headers = ret.Headers;
            if (!_origin.IsNullOrEmpty())
                headers["Origin"] = _origin;
            headers["Sec-WebSocket-Key"] = _base64Key;
            _protocolsRequested = _protocols != null;
            if (_protocolsRequested)
                headers["Sec-WebSocket-Protocol"] = _protocols.ToString(", ");
            _extensionsRequested = _compression != CompressionMethod.None;
            if (_extensionsRequested)
                headers["Sec-WebSocket-Extensions"] = createExtensions();
            headers["Sec-WebSocket-Version"] = _version;
            AuthenticationResponse authRes = null;
            if (_authChallenge != null && _credentials != null)
            {
                authRes = new AuthenticationResponse(_authChallenge, _credentials, _nonceCount);
                _nonceCount = authRes.NonceCount;
            }
            else if (_preAuth)
            {
                authRes = new AuthenticationResponse(_credentials);
            }
            if (authRes != null)
                headers["Authorization"] = authRes.ToString();
            if (_cookies.Count > 0)
                ret.SetCookies(_cookies);
            return ret;
        }

     该办法用于客户端成立一个websocket请求,制造握手请求。var ret =
HttpRequest.CreateWebSocketRequest(_uri);遵照传入的uri调用HttpRequest的艺术创设请求。该措施主要操作http尾部音信,创制请求。

四.总结

 
 对于那几个组件,个人感觉依然有局地用,这些组件很好的贯彻了websocket,那里也只是简短的牵线,需求采纳的同学,能够自取,因为该器件是开源的,所以有些其实际情形形中得以活动修改源码,达到最大限度的扩充性。在品种的技巧选拔中,个人比较看好开源免费的框架和组件,不仅是种类预算的标题,更有便民扩张的效果。

相关文章