当前位置: 代码网 > it编程>编程语言>Asp.net > 【C#】WebSoket 演示(使用websocket-sharp库)

【C#】WebSoket 演示(使用websocket-sharp库)

2024年08月03日 Asp.net 我要评论
Example 3服务器+ Example1 客户端示例3此源代码片段包含了如何使用WebSocketSharp库来创建一个HTTP服务器,并提供WebSocket服务。 分析整个代码,我们可以归纳出以下关键信息:导入了一系列重要的命名空间,包括系统配置、加密库、文本、WebSocket等。定义了Example3名称空间和包含Main方法的Program类,作为HTTP服务器和WebSocket服...

fabc738911d3aa0daa9d03b8cef1ca66.png

a59c7776742e213c865ec6fbde1391b4.png

example 3服务器+ example1 客户端

示例3

e8badb8b216a23199da67800248b24fb.png

此源代码片段包含了如何使用websocketsharp库来创建一个http服务器,并提供websocket服务。 分析整个代码,我们可以归纳出以下关键信息:

  1. 导入了一系列重要的命名空间,包括系统配置、加密库、文本、websocket等。

  2. 定义了example3名称空间和包含main方法的program类,作为http服务器和websocket服务的入口点。

  3. http服务器使用4649端口实例化,同时注释掉的代码展示了其他可能的方式来实例化http服务器(包括带安全连接的https,以及监听不同网络地址和端口的服务器实例)。

  4. 当服务器运行在debug模式下,可以设置日志级别、响应等待时间以及清理策略。

  5. 注释掉的代码示例说明了如何设置服务器的ssl配置,以及如何设置基本或摘要型的http身份验证。

  6. 服务器利用httpserver.documentrootpath设置了文档根目录路径。

  7. 通过onget事件处理程序来处理http get请求,可以读取文件并根据文件内容类型设置响应头和正文。

  8. 服务器添加了echochat两个websocket服务。

  9. 注释掉的代码中包括了websocket服务的详细初始化示例,例如设置协议、校验器和对服务器发送的cookie进行校验等。

  10. 服务器启动并开始监听,在控制台上显示一些运行信息。

  11. 最后,通过读取输入来停止http服务器

综上所述,本段代码提供了使用websocketsharp库创建符合个人需要的http服务器与websocket服务的多种示例和配置方法。通过此代码,可以开启一个支持websocket通信的服务器,并可通过相关配置来实现安全连接、http认证和基于文档根路径的内容服务能力。

57a67985fe5803c188c48885a2b2ebac.jpeg

app.config文件

下面代码初始化一个基于websocketsharp库的websocket服务器,它允许客户端通过websocket协议连接进行通信,并提供http服务,可以响应基于http的get请求。提供静态文件服务和websocket回显(echo)/聊天(chat)服务。支持通过不同方式指定服务的地址和端口,包含了调试模式下的日志等级设置,以及生产模式下的ssl/tls证书配置和http认证机制的配置,但这些功能默认是被注释掉的。服务器通过控制台命令启动和停止,并能在控制台输出当前服务的状态信息。

using system; // 引入system命名空间
using system.configuration; // 引入system.configuration命名空间,用于访问配置文件
using system.security.cryptography.x509certificates; // 引入system.security.cryptography.x509certificates命名空间,用于处理证书
using system.text; // 引入system.text命名空间,包含编码和字符集的功能
using websocketsharp; // 引入websocketsharp命名空间,一个实现websocket协议的c#库
using websocketsharp.net; // 引入websocketsharp.net命名空间,提供网络相关的功能
using websocketsharp.server; // 引入websocketsharp.server命名空间,用于创建和管理websocket服务器


// 定义了一个名为example3的命名空间
namespace example3
{
  // 定义了一个program类
  public class program
  {
    // 主函数
    public static void main (string[] args)
    {
      // 创建httpserver类的新实例。
      //
      // 如果需要提供安全连接(即https),应使用带有'secure'参数设置为true
      // 或者带有https协议的http url来创建新实例。


      var httpsv = new httpserver (4649); // 在4649端口上实例化httpserver
      // var httpsv = new httpserver (5963, true); // 使用ssl在5963端口上实例化httpserver(代码暂时被注释)


      // 下面的被注释的代码块展示了其他创建httpserver实例的方式。
      // 例如绑定到所有ip地址、绑定到ipv6地址、通过具体ip实例化等等。
      /*注释掉的代码展示了多种不同的方法来创建httpserver的实例,包括监听不同的网络接口(所有网络、ipv4回环地址、ipv6回环地址)、监听不同的端口(常规端口、安全端口)、以及支持安全连接(ssl/tls)。代码被注释意味着虽然是可用的选项,但当前不是活动状态。这些代码为开发者提供了灵活性,在不同场景下快速调整服务器监听的网络接口和端口。*/
      // 使用ssl,在5963端口上创建一个支持安全连接的httpserver实例(代码被注释)
        // var httpsv = new httpserver (5963, true); 
        // 在所有网络接口的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.any, 4649); 
        // 在所有网络接口的5963端口上创建支持ssl的httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.any, 5963, true); 
        // 在所有ipv6地址的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.ipv6any, 4649); 
         // 在所有ipv6地址的5963端口上创建支持ssl的httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.ipv6any, 5963, true);
         // 通过http协议,在所有网络接口的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("http://0.0.0.0:4649");
        // 通过https协议,在所有网络接口的5963端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("https://0.0.0.0:5963");
        // 通过http协议,在所有ipv6地址的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("http://[::0]:4649");
        // 通过https协议,在所有ipv6地址的5963端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("https://[::0]:5963"); 
        // 在回环接口(localhost)的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.loopback, 4649); 
        // 在回环接口(localhost)的5963端口上创建支持ssl的httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.loopback, 5963, true); 
        // 在ipv6回环接口(localhost)的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.ipv6loopback, 4649); 
        // 在ipv6回环接口(localhost)的5963端口上创建支持ssl的httpserver实例(代码被注释)
        // var httpsv = new httpserver (system.net.ipaddress.ipv6loopback, 5963, true); 
        // 通过http协议,在localhost的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("http://localhost:4649"); 
        // 通过https协议,在localhost的5963端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("https://localhost:5963"); 
        // 通过http协议,在127.0.0.1(ipv4回环地址)的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("http://127.0.0.1:4649"); 
         // 通过https协议,在127.0.0.1(ipv4回环地址)的5963端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("https://127.0.0.1:5963");
        // 通过http协议,在[::1](ipv6回环地址)的4649端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("http://[::1]:4649"); 
        // 通过https协议,在[::1](ipv6回环地址)的5963端口上创建httpserver实例(代码被注释)
        // var httpsv = new httpserver ("https://[::1]:5963");


#if debug
      // 若是处于debug模式,以下参数会被设置。
      httpsv.log.level = loglevel.trace; // 日志级别被设置为trace


      // 以下是在debug模式下可能会设置的其他参数。
       // 更改响应websocket ping或close的等待时间为2秒(代码被注释)
      // httpsv.waittime = timespan.fromseconds (2); 
      // httpsv.keepclean = false; // 不定期移除不活跃的websocket会话(代码被注释)


#endif
        /*被注释掉的代码展示了如何对httpserver实例进行配置,包括配置安全连接(设置服务器证书)、提供http认证(设置认证方案,用户凭证查找函数)以及解决等待处于time_wait状态的套接字的问题。被注释意味着这些配置在当前不被应用,这些代码为开发者提供了灵活性,在不同场景下快速调整服务器的配置。*/
      // 若要启用具有安全性的连接(ssl/tls),需要取消以下部分的注释,
      // 并指定服务器证书的路径与密码。
        // 提供安全连接
        /*
        var cert = configurationmanager.appsettings["servercertfile"]; // 获取服务器证书文件路径
        var passwd = configurationmanager.appsettings["certfilepassword"]; // 获取服务器证书文件密码
        httpsv.sslconfiguration.servercertificate = new x509certificate2 (cert, passwd); // 创建x509证书实例并设置为服务器证书(代码段被注释)
        */


        // 提供http认证(基础认证/摘要认证)
        /*
        httpsv.authenticationschemes = authenticationschemes.basic; // 设置认证方案为基础认证
        httpsv.realm = "websocket test"; // 设置领域/域名为"websocket test"
        httpsv.usercredentialsfinder = id => {
            var name = id.name; // 获取用户名


            // 返回用户名、密码以及角色
            return name == "nobita"
                ? new networkcredential (name, "password", "gunfighter")
                : null; // 如果找不到用户的凭证,则返回null(代码段被注释)
        };
        */


        // 解决等待处于time_wait状态的套接字问题
        // httpsv.reuseaddress = true; // 设置可重用地址(代码被注释)


 


      // 设置文档根路径。
      httpsv.documentrootpath = configurationmanager.appsettings["documentrootpath"];


      // 设置http get请求处理事件。
        httpsv.onget += (sender, e) => { // 为httpsv实例的onget事件绑定一个事件处理程序
            var req = e.request; // 获取请求对象
            var res = e.response; // 获取响应对象


            var path = req.rawurl; // 获取请求的rawurl属性,即原始请求路径


            if (path == "/") // 如果请求路径是根目录
            path += "index.html"; // 则将路径改为"index.html"


            byte[] contents; // 定义一个字节数组来存放文件内容


            if (!e.tryreadfile (path, out contents)) { // 尝试读取指定路径的文件内容到contents数组中
            res.statuscode = (int) httpstatuscode.notfound; // 如果文件不存在,设置响应状态码为404(未找到)


            return; // 结束事件处理
            }


            // 以下根据请求文件的类型设置content-type响应头
            if (path.endswith(".html")) { // 如果文件是html文件
            res.contenttype = "text/html"; // 设置响应内容类型为text/html
            res.contentencoding = encoding.utf8; // 设置响应内容的编码为utf-8
            }
            else if (path.endswith(".js")) { // 如果文件是javascript文件
            res.contenttype = "application/javascript"; // 设置响应内容类型为application/javascript
            res.contentencoding = encoding.utf8; // 同样设置编码为utf-8
            }


            res.contentlength64 = contents.longlength; // 设置响应内容的长度


            res.close(contents, true); // 将内容发送给客户端并关闭响应
        };


      // 添加websocket服务。
      httpsv.addwebsocketservice<echo> ("/echo"); // 添加echo服务
      httpsv.addwebsocketservice<chat> ("/chat"); // 添加chat服务
      // websocket服务的初始化(如果需要初始化参数)。下面的多个注释代码块用于配置服务。


      httpsv.start(); // 启动httpserver


      // 如果服务器已经开始监听,则输出一些基本的服务信息。
      if (httpsv.islistening) {
        console.writeline ("listening on port {0}, and providing websocket services:", httpsv.port);
        foreach (var path in httpsv.websocketservices.paths)
          console.writeline ("- {0}", path); // 输出提供服务的路径
      }


      console.writeline ("\npress enter key to stop the server..."); // 提示按下回车停止服务器
      console.readline (); // 等待用户输入


      httpsv.stop (); // 停止httpserver
    }
  }
}

启动服务:

listening on port 4649, and providing websocket services:
- /echo
- /chat


press enter key to stop the server...

下面代码定义了一个名为chat的类,该类继承自websocketbehavior类,用于处理websocket服务器的一个聊天服务。在新的websocket连接建立时获取用户名,并向所有已连上的会话广播该用户已上线的消息。当收到消息时,将该用户的用户名和消息内容进行拼装,并广播给所有已连上的会话。当websocket连接断开时,广播该用户已下线的消息。整个chat类就是一个简单的聊天室服务的实现。

using system; // 引用system命名空间
using system.threading; // 引用system.threading命名空间,提供多线程相关的功能
using websocketsharp; // 引用websocketsharp命名空间,一个实现websocket协议的c#库
using websocketsharp.server; // 引用websocketsharp.server命名空间,用于创建和管理websocket服务器


// 定义example3名字空间
namespace example3
{
  // 定义公共类chat,继承自websocketbehavior
  public class chat : websocketbehavior
  {
    private string _name; // 私有字符串变量,表示聊天的用户名
    private static int _number = 0; // 私有静态整型变量,与用户名关联
    private string _prefix; // 私有字符串变量,表示用户名前缀


    // 构造函数
    public chat ()
    {
      _prefix = "anon#"; // 默认的用户名前缀是“anon#”
    }


    // prefix 属性的get和set方法
    public string prefix {
      get {
        return _prefix;
      }


      set {
        _prefix = !value.isnullorempty () ? value : "anon#";
      }
    }


    // 获取用户名的私有方法
    private string getname ()
    {
      var name = context.querystring["name"]; // 获取querystring中的"name"字段的值作为用户名


      return !name.isnullorempty () ? name : _prefix + getnumber (); // 如果"name"字段非空,则用户名为其值,否则,用户名为前缀+_number
    }


    // 获取_number的私有方法,并使用interlocked增量操作该变量,保证线程安全
    private static int getnumber ()
    {
      return interlocked.increment(ref _number);
    }


    // 覆盖基类的onclose方法,该方法在websocket连接关闭时被调用
    protected override void onclose (closeeventargs e)
    {
      if (_name == null)
        return;


      var fmt = "{0} got logged off..."; // 定义消息格式
      var msg = string.format (fmt, _name); // 格式化消息字符串


      sessions.broadcast (msg); // 向所有连接的会话广播消息
    }


    // 覆盖基类的onmessage方法,该方法在收到websocket消息时被调用
    protected override void onmessage (messageeventargs e)
    {
      var fmt = "{0}: {1}"; // 定义消息格式
      var msg = string.format (fmt, _name, e.data); // 格式化消息字符串


      sessions.broadcast (msg); // 向所有连接的会话广播消息
    }


    // 覆盖基类的onopen方法,该方法在建立新的websocket连接后立即被调用
    protected override void onopen ()
    {
      _name = getname (); // 获取用户名


      var fmt = "{0} has logged in!"; // 定义消息格式
      var msg = string.format (fmt, _name); // 格式化消息字符串


      sessions.broadcast (msg); // 向所有连接的会话广播消息
    }
  }
}

下面代码定义了名为echo的类,该类继承自websocketbehavior,用于处理websocket服务器上的回声服务。当echo服务的websocket连接收到客户端送来的消息时,它简单地将相同的消息数据直接返回给客户端。这个类通常用于测试客户端与服务器的连接是否正常,检查消息的去程和回程延迟。

using system; // 引入system命名空间
using websocketsharp; // 引入websocketsharp命名空间,一个实现websocket协议的c#库
using websocketsharp.server; // 引入websocketsharp.server命名空间,用于创建和管理websocket服务器


// 定义example3名字空间
namespace example3
{
  // 定义公共类echo,继承自websocketbehavior
  public class echo : websocketbehavior
  {
    // 覆盖基类的onmessage方法,该方法在收到websocket消息时被调用
    protected override void onmessage(messageeventargs e)
    {
      send(e.data); // 将收到的消息数据发送回客户端,实现回声(echo)功能
    }
  }
}

示例1

af6eaed453175458d653b19ba0efa8e9.png

这段代码展示了如何使用websocketsharp库创建一个websocket客户端,连接到websocket服务器,并发送和接收消息。它提供了处理打开连接、接收消息、发生错误以及关闭连接的事件处理程序。代码还包括了调试相关的设置,以及一些被注释的代码块来展示如何配置websocket客户端(例如ssl证书验证、发送凭证、处理cookies等),但这些部分目前并未启用。用户通过控制台可以输入消息发送到服务器,输入"exit"来关闭程序。

using system; // 引入system命名空间,它是最基础的命名空间
using system.threading; // 引入多线程相关的命名空间
using websocketsharp; // 引入websocketsharp库,它提供了websocket协议的实现
using websocketsharp.net; // 引入网络相关的命名空间


namespace example // 定义一个名为example的命名空间
{
  public class program // 定义一个公共类program
  {
    public static void main (string[] args) // 主函数,程序入口点
    {
        // 创建 websocket 类的新实例。
       //
       // websocket类继承了system.idisposable接口,因此可以
       // 使用using 语句。 websocket 连接将被关闭
       // 当控件离开 using 块时关闭状态 1001(离开)。
       //
       // 如果您想通过安全连接连接到服务器,
       // 您应该使用 wss 方案 websocket url 创建一个新实例。


      using (var ws = new websocket ("ws://localhost:4649/echo")) // 创建一个websocket实例连接到指定的服务端地址和端口
      //using (var ws = new websocket ("wss://localhost:5963/echo"))
      //using (var ws = new websocket ("ws://localhost:4649/chat"))
      //using (var ws = new websocket ("wss://localhost:5963/chat"))
      //using (var ws = new websocket ("ws://localhost:4649/chat?name=nobita"))
      //using (var ws = new websocket ("wss://localhost:5963/chat?name=nobita"))
      {
        // 设置websocket事件


        ws.onopen += (sender, e) => ws.send ("hi, there!"); // 当websocket连接建立时,发送一条消息"hi, there!"


        ws.onmessage += (sender, e) => { // 当从服务端接收到消息时,执行该事件
            var fmt = "[websocket message] {0}"; // 定义一个格式字符串
            var body = !e.isping ? e.data : "a ping was received."; // 如果接收到的不是ping消息,则输出数据,否则输出"a ping was received."


            console.writeline (fmt, body); // 将消息输出到控制台
          };


        ws.onerror += (sender, e) => { // 当发生错误时,执行该事件
            var fmt = "[websocket error] {0}"; // 定义一个格式字符串


            console.writeline (fmt, e.message); // 将错误信息输出到控制台
          };


        ws.onclose += (sender, e) => { // 当websocket连接关闭时,执行该事件
            var fmt = "[websocket close ({0})] {1}"; // 定义一个格式字符串


            console.writeline (fmt, e.code, e.reason); // 将关闭信息输出到控制台
          };
  
#if debug
        // 调试时设置的额外选项
        ws.log.level = loglevel.trace; // 设置日志级别


        // 设置等待ping或close的响应时间为10秒(代码被注释)
        // ws.waittime = timespan.fromseconds (10);


        // 当接收到ping时触发websocket.onmessage事件(代码被注释)
        // ws.emitonping = true;
#endif


        // 开启消息压缩功能
        // ws.compression = compressionmethod.deflate; //(代码被注释)


        // 验证服务器证书(代码段被注释)
        /*
        ws.sslconfiguration.servercertificatevalidationcallback =
          (sender, certificate, chain, sslpolicyerrors) => {
            // 省略了输出证书信息的代码
            return true; // 如果服务器证书有效
          };
         */


        // 发送http认证信息(基础认证或摘要认证)(代码被注释)
        // ws.setcredentials ("nobita", "password", false);


        // 发送来源页首部(代码被注释)
        // ws.origin = "http://localhost:4649";


        // 发送cookies(代码被注释)
        // ws.setcookie (new cookie ("name", "nobita"));
        // ws.setcookie (new cookie ("roles", "\"idiot, gunfighter\""));


        // 通过http代理服务器连接(代码被注释)
        // ws.setproxy ("http://localhost:3128", "nobita", "password");


        // 开启重定向(代码被注释)
        // ws.enableredirection = true;


        ws.connect (); // 连接到服务器


        // 异步连接到服务器(代码被注释)
        // ws.connectasync ();


        console.writeline ("\ntype 'exit' to exit.\n"); // 输出提示信息


        while (true) { // 开始一个循环,持续监听输入
          thread.sleep (1000); // 线程休眠1秒
          console.write ("> "); // 控制台输出"> "


          var msg = console.readline (); // 读取用户输入


          if (msg == "exit") // 如果输入的是"exit"
            break; // 跳出循环


          ws.send (msg); // 将输入的消息发送到websocket服务器
        }
      }
    }
  }
}

示例2

e5bf9e54135c4af7463802cc6cd95997.png

这段代码演示了如何使用websocketsharp库创建一个websocket服务器,并监听特定的端口(例如4649)。服务器被配置为提供两种websocket服务:echo和chat。服务器的日志级别在调试模式下被设置为trace,以便记录详细信息,方便开发者调试。此外,代码还包含了一些注释掉的部分,展示了如何进行更多高级配置,例如配置ssl/tls安全连接,启用http基础或摘要认证,设置地址重用,定制websocket服务的初始化参数等。其中大多数配置目前都被注释了,所以不会生效。服务器启动后,会打印正在监听的端口和提供的websocket服务路径。代码的最后部分等待用户按回车键来停止服务器。

using system; // 使用system命名空间,包含基本的类定义和类型。
using system.configuration; // 引用配置管理相关的类,如读取配置文件等。
using system.security.cryptography.x509certificates; // 引用安全性和加密相关的类,特别是处理x509证书。
using websocketsharp; // 引用websocketsharp库,它提供实现websocket协议的类。
using websocketsharp.net; // 引用网络相关的类。
using websocketsharp.server; // 引用websocket服务器相关的类。


namespace example2 // 定义一个名为example2的命名空间。
{
  public class program // 定义一个公共类program。
  {
    public static void main (string[] args) // 主函数,程序的入口点。
    {
      // 创建一个新的websocketserver实例。
      var wssv = new websocketserver (4649); // 初始化一个监听端口为4649的websocket服务器实例。
      //var wssv = new websocketserver (5963, true); // (被注释)同时指出此服务器为安全连接(wss)。


        //var wssv = new websocketserver (system.net.ipaddress.any, 4649); // 使用任意ipv4地址。
        //var wssv = new websocketserver (system.net.ipaddress.any, 5963, true); // 使用任意ipv4地址和提供安全连接。


        //var wssv = new websocketserver (system.net.ipaddress.ipv6any, 4649); // 使用任意ipv6地址。
        //var wssv = new websocketserver (system.net.ipaddress.ipv6any, 5963, true); // 使用任意ipv6地址和提供安全连接。


        //var wssv = new websocketserver ("ws://0.0.0.0:4649"); // 使用ipv4通配地址。
        //var wssv = new websocketserver ("wss://0.0.0.0:5963"); // 使用ipv4通配地址和提供安全连接。


        //var wssv = new websocketserver ("ws://[::0]:4649"); // 使用ipv6通配地址。
        //var wssv = new websocketserver ("wss://[::0]:5963"); // 使用ipv6通配地址和提供安全连接。


        //var wssv = new websocketserver (system.net.ipaddress.loopback, 4649); // 使用本机回环地址ipv4。
        //var wssv = new websocketserver (system.net.ipaddress.loopback, 5963, true); // 使用本机回环地址ipv4和提供安全连接。


        //var wssv = new websocketserver (system.net.ipaddress.ipv6loopback, 4649); // 使用本机回环地址ipv6。
        //var wssv = new websocketserver (system.net.ipaddress.ipv6loopback, 5963, true); // 使用本机回环地址ipv6和提供安全连接。


        //var wssv = new websocketserver ("ws://localhost:4649"); // 使用localhost和端口4649。
        //var wssv = new websocketserver ("wss://localhost:5963"); // 使用localhost和端口5963提供安全连接。


        //var wssv = new websocketserver ("ws://127.0.0.1:4649"); // 使用ipv4的本机回环地址和端口4649。
        //var wssv = new websocketserver ("wss://127.0.0.1:5963"); // 使用ipv4的本机回环地址和端口5963提供安全连接。


        //var wssv = new websocketserver ("ws://[::1]:4649"); // 使用ipv6的本机回环地址和端口4649。
        //var wssv = new websocketserver ("wss://[::1]:5963"); // 使用ipv6的本机回环地址和端口5963提供安全连接。






#if debug
      // 更改日志级别(只有在调试模式下起作用)。
      wssv.log.level = loglevel.trace; // 设置日志级别为trace(追踪),目的是显示尽可能多的调试信息。


      // 更改websocket ping或close回应的等待时间(代码被注释)。
      // wssv.waittime = timespan.fromseconds (2);


      // 不定期移除非活动会话(代码被注释)。
      // wssv.keepclean = false;
#endif
      // 提供安全连接(代码段被注释)。
      /*
      var cert = configurationmanager.appsettings["servercertfile"]; // 从配置文件获取证书文件路径。
      var passwd = configurationmanager.appsettings["certfilepassword"]; // 从配置文件获取证书密码。
      wssv.sslconfiguration.servercertificate = new x509certificate2 (cert, passwd); // 创建证书实例并应用于服务器的ssl配置。
       */


      // 提供http认证(基础/摘要)(代码段被注释)。
      /*
      wssv.authenticationschemes = authenticationschemes.basic; // 设置认证方案为basic(基础认证)。
      wssv.realm = "websocket test"; // 设置认证域为"websocket test"。
      wssv.usercredentialsfinder = id => { // 设置用户凭据查找函数。
          var name = id.name; // 获取用户名。


          // 返回用户名、密码和角色。
          return name == "nobita" // 如果用户名为"nobita",则返回凭据。
                 ? new networkcredential (name, "password", "gunfighter")
                 : null; // 如果用户凭据未找到,返回null。
        };
       */


      // 解决等待处于time_wait状态的套接字(代码被注释)。
      // wssv.reuseaddress = true;


      // 添加websocket服务。
      wssv.addwebsocketservice<echo> ("/echo"); // 添加名为"/echo"的websocket回音服务。
      wssv.addwebsocketservice<chat> ("/chat"); // 添加名为"/chat"的websocket聊天服务。


      // 添加websocket服务并进行初始化(代码段被注释)。
        // 用初始化方案添加websocket服务(以下代码被注释,并没有在实际程序中运行)。
        /*
        wssv.addwebsocketservice<chat> (
        "/chat",
        s => {
            s.prefix = "anon#"; // 设置聊天服务的前缀。


            // 发送包含子协议名称的sec-websocket-protocol头。
            s.protocol = "chat"; // 为聊天服务设置子协议。


            // 忽略sec-websocket-extensions头。
            s.ignoreextensions = true; // 忽略websocket扩展。


            // 在接收到ping时发出websocket.onmessage事件。
            s.emitonping = true; // 允许ping消息触发onmessage事件。


            // 验证origin头。
            s.originvalidator = val => {
                // 检查origin头的值,如果有效则返回true。
                uri origin;
                return !val.isnullorempty()
                    && uri.trycreate(val, urikind.absolute, out origin)
                    && origin.host == "localhost"; // 如果来源是localhost,则认为是有效的。
            };


            // 验证cookies。
            s.cookiesvalidator = (req, res) => {
                // 检查请求中的cookies,并在必要时设置要发送给客户端的cookies。
                foreach (var cookie in req) {
                cookie.expired = true; // 将请求中的所有cookie设置为过期。
                res.add(cookie); // 将过期的cookie添加到响应中。
                }
                return true; // 如果验证有效则返回true。
            };
        }
        );
        */


      wssv.start (); // 启动websocket服务器。


      // 如果websocket服务器正在监听,则输出信息。
      if (wssv.islistening) {
        console.writeline ("listening on port {0}, and providing websocket services:", wssv.port); // 打印监听端口及服务信息。


        // 循环通过websocket服务器提供的服务路径,并打印出来。
        foreach (var path in wssv.websocketservices.paths)
          console.writeline ("- {0}", path); // 打印服务路径。
      }


      console.writeline ("\npress enter key to stop the server..."); // 提示按回车键停止服务器。
      console.readline (); // 等待用户输入回车键。


      wssv.stop (); // 停止websocket服务器。
    }
  }
}

笔记

68635649ca738c4b174a0e2aded3d4cf.png

71a6b49677888a8937eccae70615117b.png

8c9e48b975b5a130232f4610be8b1e59.png

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com