C Implementation WebSocket Protocol Client and Server websocket sharp Component Instance Analysis

  • 2021-12-11 18:40:53
  • OfStack

Seeing the title of this article, it is estimated that many people will ask if this component is somewhat boring. When it comes to web communication, many people will think of ASP. NET SignalR, or Nodejs, etc., to realize web network real-time communication. There are some conceptual problems related to web real-time communication, so we will not introduce them specifically here. Those who are interested can make their own Baidu.

Below, we introduce the related contents of one WebSocket component, websocket-sharp.

1. websocket-sharp Component Overview

websocket-sharp is a client and server of C # implementing websocket protocol, and websocket-sharp supports RFC 6455;; WebSocket client and server; Message compression extension; Secure connection; HTTP authentication; Query string, starting title, and Cookie; Connect through HTTP proxy server; . NET Framework 3.5 or later (including compatible environments such as Mono).

websocket-sharp is a single 1 component, websocket-sharp. dll. websocket-sharp was developed with MonoDevelop. So a simple way to set up 1 is to open websocket-sharp. sln and run the build of the websocket-sharp project using any build configuration in MonoDevelop (for example, Debug).

The websocket-sharp component was added to the. NET project, and if you want to use the DLL in the Unity project, you should add it to any folder in the project in the Unity Editor. In the project of Unity, Unity Free has one constraint: the security sandbox of Webplayer (this server is not provided in Web Player); WebGL network (not available in WebGL); Not applicable to such UWP; Limited support for System. IO. Compression (compression extensions are not available on Windows); NET Socket support for iOS/Android (iOS/Android Pro is required if your Unity is earlier than Unity 5); The. NET API 2.0 compatibility level for iOS/Android. The. NET API 2.0 compatibility level for iOS/Android may need to be fixed after. NET 2.0 for missing features, such as System. Func < ... > Agent (so I have added it to the asset package).

2. How to use websocket-sharp components

1. WebSocket client


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);
   }
  }
 }
}

From the above code example, create a new instance of the class using WebSocketWebSocket URL to connect. 1 WebSocket. OnOpen Event that occurs when an WebSocket connection has been established. WebSocket. OnMessage WebSocket receives a message when an event occurs. 1 WebSocket. OnClose Event that occurs when the connection to WebSocket is closed. If you want to connect to the server asynchronously, you should use this WebSocket. ConnectAsync () method. You can use the WebSocket. Send (string), WebSocket. Send (byte []), or WebSocket. Send (System. IO. FileInfo) methods to send data. If you want to send data asynchronously, you should use this WebSocket. SendAsync method. If you want to explicitly close the connection, you should use this WebSocket. Close method.

2. WebSocket Server


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 ();
  }
 }
}

To define the behavior of any WebSocket service by creating a class that inherits the WebSocketBehavior class. You can use WebSocketServer by using WebSocketServer. AddWebSocketService < TBehaviorWithNew > (string) or WebSocketServer. AddWebSocketService < TBehavior > (string, Func < TBehavior > ) Method to add any WebSocket service to the specified behavior and path of the service. wssv. Start (); Start the WebSocket server. wssv. Stop (code, reason); Stop the WebSocket server.

3. Message compression


ws.Compression = CompressionMethod.Deflate;

4. HTTP Authentication


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

5. Connect through an HTTP proxy server


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

3. Parsing the core object of websocket-sharp component

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;
   }
  }

Using an WebSocket connection to send the specified data, there are multiple overloaded versions of this method, and the method is also implemented asynchronously. This method returns a Boolean parameter indicating whether the message was sent successfully. The method takes two parameters, Opcode is an enumerated type that represents the WebSocket frame type. The enumeration type values are Cont (equal to value 0 for consecutive frames), Text (equivalent to value 1 for text box), Binary (equivalent to value 2 for binary frame), Close (equivalent to value 8 for connection closing frame), Ping (equivalent to value 9 for ping frame), Pong (equivalent to value 10 for pong box). stream represents a stream object. This method sets lock operation to prevent deadlock when concurrent. However, there are still some problems in catching exceptions in the code. This method directly captures exception exceptions, which will lead to the program capturing all exceptions in the code block, which will affect the stability and repairability of the code. The best way to deal with exception capture is to restore the program.

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);
  }

This method asynchronously closes the WebSocket connection in the specified manner, taking two parameters, CloseStatusCode, a status code representing the reason for the closure, which is of an enumerated type. reason indicates the reason for the shutdown. The size must be 123 bytes or less. if (! CheckParametersForClose (code, reason, _ client, out msg) check parameter off.

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;
    }

This method is used for the client to create an websocket request and create a handshake request. var ret = HttpRequest. CreateWebSocketRequest (_ uri); The request is created by calling the method of HttpRequest from the incoming uri. This method mainly operates http header information and creates a request.

4. Summary

For this component, personal feeling is still some use, this component is a good implementation of websocket, here is only a simple introduction, students who need to use, can take their own, because the component is open source, so some actual situations can modify their own source code to maximize extensibility. In the choice of project technology, I prefer open source and free framework and components, which is not only a problem of project budget, but also more convenient to expand.


Related articles: