首页 > 编程语言 >C#创建WebSocket服务端

C#创建WebSocket服务端

时间:2024-12-08 22:45:57浏览次数:3  
标签:WebSocket C# ws 消息 连接 服务端 客户端

使用 C#创建 WebSocket 服务端的方法

1. 引入必要的命名空间

using System.Text; // 用于发送和接收信息时处理文本
using System.Net;   // 用于处理网络连接
using System.Net.WebSockets; // 用于处理WebSocket连接

2. 实例化 HttpListener


const string HOST = "localhost";     // 监听的主机名
const int PORT = 3030;              // 监听的端口号

HttpListener listener = new HttpListener(); // 实例化HttpListener,这个需要作为一个全局变量
listener.Prefixes.Add($"http://{HOST}:{PORT}/");  // 设置监听的URL
listener.Start(); // 开始监听

3. 处理客户端的请求

async static Task ListenClientConnections()
{
    while (true)
    {
        // 等待客户端的连接
        Console.WriteLine("等待客户端连接");
        HttpListenerContext context = await listener.GetContextAsync();
        // 判断此连接是否为WebSocket的请求
        if (context.Request.IsWebSocketRequest)
        {
            Console.WriteLine($"接收到客户端连接");
            // 这时候,我们可以用WebSocket来接受客户端的连接
            WebSocket webSocket = context.AcceptWebSocketAsync(null).Result.WebSocket;
            // 这时候我们可以根据需要来处理客户端的消息
            while (webSocket.State == WebSocketState.Open)
            {
                // 等待客户端的消息
                byte[] buffer = new byte[1024]; // 定义一个缓冲区大小为1KB
                ArraySegment<byte> segment = new ArraySegment<byte>(buffer);    // 定义一个数组段

                CancellationToken cancellationToken = CancellationToken.None;   // 定义一个取消标记

                // 这时候这里一直等待客户端的消息
                Console.WriteLine("等待客户端消息");
                WebSocketReceiveResult result = await webSocket.ReceiveAsync(segment, cancellationToken);

                // 文本类型的消息
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    // 这里可以对客户端的消息进行处理
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);

                    // 给客户端发送消息
                    string responseMessage = $"接收到客户端的消息: {message}";
                    Console.WriteLine(responseMessage);
                    byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);

                    await webSocket.SendAsync(
                        responseBuffer,     // 发送的消息,字节数组类型
                        WebSocketMessageType.Text,  // 消息类型为文本
                        true,   // 最后一帧,如果为false,则表示后面还有数据
                        CancellationToken.None    // 取消标记
                    );
                }
            }
            Console.WriteLine("客户端连接断开");
        }
    }
}

4. 启动服务端

ListenClientConnections().Wait(); // 启动监听客户端连接的异步方法

5. 客户端连接

在这里我们用 javascript 的 WebSocket 来模拟客户端的连接,并向服务端发送消息。

let ws = new WebSocket("ws://localhost:3030/");
ws.onopen = function () {
  console.log("连接到服务端");

  // 发送消息
  ws.send("Hello World!!!");
};

ws.onclose = function () {
  console.log("与服务端连接断开");
};

ws.onmessage = function ({ data }) {
  console.log("接收到服务端消息");
  console.log(data);

  // ws.send("Hello World!!!");  // 猜猜会发生什么?
  ws.close(); // 关闭连接
  console.log("关闭与服务端的连接");
};

ws.onerror = function () {
  console.log("WebSocket连接发生错误");
};

6. 运行结果

在服务端的控制台中,我们可以看到:

等待客户端连接
接收到客户端连接
等待客户端消息
接收到客户端的消息: Hello World!!!
等待客户端消息
客户端连接断开
等待客户端连接

在客户端的控制台中,我们可以看到:

连接到服务端
接收到服务端消息
接收到客户端的消息: Hello World!!!
关闭与服务端的连接
与服务端连接断开

到这里,我们就完成了 C# 创建 WebSocket 服务端的方法。

完整代码

using System.Text; // 用于发送和接收信息时处理文本
using System.Net;   // 用于处理网络连接
using System.Net.WebSockets; // 用于处理WebSocket连接

namespace Test.Program
{
    static class Program
    {
        static HttpListener listener;
        static void Main(string[] args)
        {
            const string HOST = "localhost";     // 监听的主机名
            const int PORT = 3030;              // 监听的端口号

            listener = new HttpListener(); // 实例化HttpListener
            listener.Prefixes.Add($"http://{HOST}:{PORT}/");  // 设置监听的URL
            listener.Start(); // 开始监听
            ListenClientConnections()
                .Wait();
        }

        async static Task ListenClientConnections()
        {
            while (true)
            {
                // 等待客户端的连接
                Console.WriteLine("等待客户端连接");
                HttpListenerContext context = await listener.GetContextAsync();
                // 判断此连接是否为WebSocket的请求
                if (context.Request.IsWebSocketRequest)
                {
                    Console.WriteLine($"接收到客户端连接");
                    // 这时候,我们可以用WebSocket来接受客户端的连接
                    WebSocket webSocket = context.AcceptWebSocketAsync(null).Result.WebSocket;
                    // 这时候我们可以根据需要来处理客户端的消息
                    while (webSocket.State == WebSocketState.Open)
                    {
                        // 等待客户端的消息
                        byte[] buffer = new byte[1024]; // 定义一个缓冲区大小为1KB
                        ArraySegment<byte> segment = new ArraySegment<byte>(buffer);    // 定义一个数组段

                        CancellationToken cancellationToken = CancellationToken.None;   // 定义一个取消标记

                        // 这时候这里一直等待客户端的消息
                        Console.WriteLine("等待客户端消息");
                        WebSocketReceiveResult result = await webSocket.ReceiveAsync(segment, cancellationToken);

                        // 文本类型的消息
                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            // 这里可以对客户端的消息进行处理
                            string message = Encoding.UTF8.GetString(buffer, 0, result.Count);

                            // 给客户端发送消息
                            string responseMessage = $"接收到客户端的消息: {message}";
                            Console.WriteLine(responseMessage);
                            byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);

                            await webSocket.SendAsync(
                                responseBuffer,     // 发送的消息,字节数组类型
                                WebSocketMessageType.Text,  // 消息类型为文本
                                true,   // 最后一帧,如果为false,则表示后面还有数据
                                CancellationToken.None    // 取消标记
                            );
                        }
                    }
                    Console.WriteLine("客户端连接断开");
                }
            }
        }
    }
}

客户端

let ws = new WebSocket("ws://localhost:3030/");
ws.onopen = function () {
  console.log("连接到服务端");

  // 发送消息
  ws.send("Hello World!!!");
};

ws.onclose = function () {
  console.log("与服务端连接断开");
};

ws.onmessage = function ({ data }) {
  console.log("接收到服务端消息");
  console.log(data);

  // ws.send("Hello World!!!");  // 猜猜会发生什么?
  ws.close(); // 关闭连接
  console.log("关闭与服务端的连接");
};

ws.onerror = function () {
  console.log("WebSocket连接发生错误");
};

标签:WebSocket,C#,ws,消息,连接,服务端,客户端
From: https://www.cnblogs.com/musehanzhi/p/18593804

相关文章

  • [题解](更新中)AtCoder Beginner Contest 383(ABC383) A~E
    A-Humidifier1照题意模拟即可,时间复杂度\(O(n)\)。点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineN110usingnamespacestd;intn,t[N],v[N],sum;signedmain(){ cin>>n; for(inti=1;i<=n;i++)cin>>t[i]>>v[i]; for(inti=1......
  • scikit-learn中的Pipeline:构建高效、可维护的机器学习流程
    我们使用scikit-learn进行机器学习的模型训练时,用到的数据和算法参数会根据具体的情况相应调整变化,但是,整个模型训练的流程其实大同小异,一般都是加载数据,数据预处理,特征选择,模型训练等几个环节。如果训练的结果不尽如人意,从数据预处理开始,再次重新训练。今天介绍的Pipeline(中文......
  • Github+PicGo搭建个人免费图床
    目录一、配置GitHub1、新建公开仓库1.1、Newrepository1.2、定义仓库名称,设置公开属性2、创建私人令牌(token)2.1、个人头像-->Settings2.2、左侧列底部点击Developersettings2.3、选择Generatenewtoken(classic)2.4、密码验证2.5、创建令牌2.6、记事本记下token二、配置Pi......
  • HCIE-15 SRv6原理与配置
    目录SRv6概述IP/MPLS网络简介MPLSLDP与RSVP-TE存在的问题SR的起源与解决方案从MPLS到SRv6SRv6的技术价值SRv6原理SRv6基本概念SRv6原理简介SRv6SRH介绍SRv6Segment介绍SRv6Segment:LocatorSRv6Segment:Function&ArgumentsSRv6Segment类型介绍SRv6Segment命名规则SRv6S......
  • 【树莓派】 Warning from apt-key: Key is stored in legacy trusted.gpg keyring (/e
    执行sudoaptupdate出现这个错误:W:http://raspbian.raspberrypi.com/raspbian/dists/bookworm/InRelease:Keyisstoredinlegacytusted.gpgkeyring(/etc/apt/trusted.gpg),seetheDEPRECATIONsectioninapt-key(8)fordetrails.解决方法:$apt-keylist|......
  • Python农产品预订商城农商对接助农系统pycharm毕业设计项目
    文章目录项目介绍具体实现截图开发技术设计思路开发与测试:核心代码部分展示文章目录/协作提纲源码/演示视频获取方式项目介绍如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术......
  • 第七章 利用CSS和多媒体美化页面
    7.1CSS链接的美化CSS链接的美化是提升网页视觉效果和用户体验的重要手段。以下是一些常见的CSS链接美化方法:7.1.1.文字链接的美化文字链接的美化主要通过CSS来实现,旨在提升链接的视觉效果和用户的交互体验。以下是一些常见的文字链接美化技巧:1.颜色与文本装饰颜色:使用鲜......
  • YOLOv11改进策略【YOLO和Mamba】| 2024 VM-UNet,高效的特征提取模块VSS block 二次创新
    一、本文介绍本文记录的是利用VM-UNet中的VSSblock优化YOLOv11的目标检测网络模型。VSSBlock与传统模块不同,它汲取了VMamba模型的优势,通过特定结构设计,在保证计算效率的同时,精准建模局部特征并学习长距离依赖,实现局部特征的高效处理与长距离依赖关系的有效学习。本文将其......
  • 第8章 利用CSS制作导航菜单
    8.1水平顶部导航栏水平莱单导航栏是网站设计中应用范围最广的导航设计,一般放置在页面的顶部。水平导航适用性强,几乎所有类型的网站都可以使用,设计难度较低。如果导航过于普通,无法容纳复杂的信息结构,就需要在内容模块较多的情况下,结合下拉子导航使用。8.1.1简单水平导航......
  • #渗透测试#红蓝对抗#SRC漏洞挖掘# Yakit(5)进阶模式-MITM中间人代理与劫持(下)
    免责声明本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章阅读。目录 Yakit(5)进阶模式-MITM中间人代理与劫持(下)History......