C#使用WebSocket与网页实时通信的实现示例

首先,要使用WebSocket与网页实时通信,需要在C#时编写WebSocket服务端,并在网页中使用JavaScript编写WebSocket客户端。下面是实现该功能的完整攻略:

C# WebSocket服务端

  1. 创建新项目。在Visual Studio里新建一个Class Library项目。
  2. 安装Newtonsoft.Json NuGet包。在项目中右击References,选择Manage NuGet Packages,搜索安装Newtonsoft.Json。
  3. 创建WebSocket服务端。在项目内新建一个类,命名为WebSocketServer,继承自Microsoft.Web.WebSockets.WebSocketHandler。
  4. 实现WebSocketServer。在WebSocketServer中,重写OnOpen、OnMessage、OnClose方法,实现WebSocket的开启、接收信息、关闭等操作。代码如下:
using Microsoft.Web.WebSockets;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWebSocketServer
{
    public class WebSocketServer : WebSocketHandler
    {
        private static List<WebSocketServer> _webSocketServers = new List<WebSocketServer>();

        private string _clientId;

        public WebSocketServer(string clientId)
        {
            _clientId = clientId;

            //将WebSocketServer实例添加到_webSocketServers列表中
            _webSocketServers.Add(this);
        }

        //发送信息
        private async Task SendMessage(string message)
        {
            if (this.WebSocket != null &&
                this.WebSocket.State == WebSocketState.Open)
            {
                //将message传入到客户端中
                await this.WebSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)),
                    WebSocketMessageType.Text, true, System.Threading.CancellationToken.None);
            }
        }

        //广播信息
        private static async Task BroadcastMessage(string message)
        {
            var copy = _webSocketServers.ToList();

            foreach (var webSocketServer in copy)
            {
                await webSocketServer.SendMessage(message);
            }
        }

        //WebSocket开启
        public override void OnOpen()
        {
            //跟客户端确认连接已建立,否则连接将会断开
            var authenticationString = Context.Headers["Sec-WebSocket-Key"] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
            var bytes = Encoding.UTF8.GetBytes(authenticationString);
            var sha1 = SHA1.Create();
            var hash = sha1.ComputeHash(bytes);
            var response = Convert.ToBase64String(hash);
            this.WebSocket.Send($"HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {response}\r\n\r\n");
        }

        //WebSocket接收信息
        public override void OnMessage(string message)
        {
            //广播信息
            BroadcastMessage(message);
        }

        //WebSocket断开
        public override void OnClose()
        {
            //将WebSocketServer实例从_webSocketServers列表中移除
            _webSocketServers.Remove(this);
            //广播离开信息
            var leaveMessage = new { Type = "leave", Id = _clientId };
            BroadcastMessage(JsonConvert.SerializeObject(leaveMessage));
        }
    }
}
  1. 创建WebSocket服务端主程序。在项目内新建一个类,命名为Program,定义Main方法。在Main方法中,实例化一个HttpListenerWrapper,并利用HttpListenerWrapper启动WebSocket服务端。代码如下:
using System;
using System.Threading.Tasks;

namespace CSharpWebSocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            var httpListenerWrapper = new HttpListenerWrapper();
            httpListenerWrapper.Start();

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }

    public class HttpListenerWrapper
    {
        // WebSocket请求的地址
        const string ListenerAddress = "http://localhost:8888/realtime";

        internal void Start()
        {
            using (var listener = new System.Net.HttpListener())
            {
                listener.Prefixes.Add(ListenerAddress + "/");
                listener.Start();

                Console.WriteLine($"开始监听地址{ListenerAddress}");

                while (true)
                {
                    var context = listener.GetContextAsync().Result;
                    if (context.Request.IsWebSocketRequest)
                    {
                        AcceptWebSocketAsync(context).Wait();
                    }
                }
            }
        }

        async Task AcceptWebSocketAsync(System.Net.HttpListenerContext context)
        {
            if (context.Request.IsWebSocketRequest)
            {
                var subProtocol = context.Request.Headers["Sec-WebSocket-Protocol"];
                var webSocketContext = await context.AcceptWebSocketAsync(subProtocol);

                var clientId = Guid.NewGuid().ToString();
                var webSocketServer = new WebSocketServer(clientId);
                webSocketServer.WebSocket = webSocketContext.WebSocket;

                Console.WriteLine($"客户端{clientId}已连接");

                await webSocketServer.OnOpenAsync();

                while (webSocketServer.WebSocket.State == WebSocketState.Open)
                {
                    var message = string.Empty;
                    var buffer = new byte[4096];
                    var result = await webSocketServer.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), System.Threading.CancellationToken.None);

                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    }
                    else if (result.MessageType == WebSocketMessageType.Binary)
                    {
                        Console.WriteLine("Binary messages are not supported");
                    }

                    await webSocketServer.OnMessageAsync(message);
                }

                await webSocketServer.OnCloseAsync(null);
            }
        }
    }
}

JavaScript WebSocket客户端

在网页中使用JavaScript的WebSocket API与WebSocket服务端进行通信。下面是一个基于WebSocket的聊天室的示例:

  1. 创建HTML文件。在HTML文件中添加一个input、一个button和一个div元素,用来输入信息和显示聊天记录。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Chat Room</title>
</head>
<body>
    <div id="logs"></div>

    <input type="text" id="input-text">
    <button id="btn-send">Send</button>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="chat.js"></script>
</body>
</html>
  1. 创建JavaScript文件。在JavaScript文件中,先定义一些初始值,如WebSocket服务端地址、WebSocket对象、客户端ID等。然后,绑定button的点击事件,在事件处理程序中,获取输入框的信息,发送到WebSocket服务端,并将信息显示在页面上。代码如下:
$(function () {
    var wsUrl = 'ws://localhost:8888/realtime';
    var socket;
    var clientId;

    socket = new WebSocket(wsUrl);

    //接收到WebSocket服务端的消息
    socket.onmessage = function (evt) {
        var message = JSON.parse(evt.data);

        switch (message.Type) {
            //有人加入聊天室
            case "join":
                $('#logs').append('<div>' + message.Username + ' joined the chat.</div>');
                break;
            //有人发消息
            case "message":
                $('#logs').append('<div>' + message.Username + ': ' + message.Content + '</div>');
                break;
            //有人离开聊天室
            case "leave":
                $('#logs').append('<div>' + message.Id + ' left the chat.</div>');
                break;
        }

        $('#logs').scrollTop($('#logs')[0].scrollHeight - $('#logs').height());
    };

    //WebSocket服务端连接已打开
    socket.onopen = function (evt) {
        clientId = generateClientId();
        var joinMessage = { Type: "join", Username: clientId };
        socket.send(JSON.stringify(joinMessage));
    };

    //WebSocket服务端连接已关闭
    socket.onclose = function (evt) {
        console.log('WebSocket closed.');
    };

    //WebSocket服务端连接出错
    socket.onerror = function (evt) {
        console.log('WebSocket error.');
    };

    //绑定"Send"按钮点击事件
    $('#btn-send').on('click', function () {
        var inputText = $('#input-text').val();
        $('#input-text').val('');
        var message = { Type: "message", Username: clientId, Content: inputText };
        socket.send(JSON.stringify(message));
        $('#logs').append('<div>Me: ' + inputText + '</div>');
    });

    //生成客户端ID
    function generateClientId() {
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }
});

以上就是使用WebSocket实现网页实时通信的完整攻略。除了以上的聊天室示例,还可以使用WebSocket实现更多的实时交互功能,如赛事直播、在线游戏等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#使用WebSocket与网页实时通信的实现示例 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • ASP.NET Core基础之中间件

    关于ASP.NET Core基础之中间件,以下是完整攻略: 什么是中间件? 中间件(Middleware)是ASP.NET Core应用程序中用于处理HTTP请求和响应的组件。中间件按照顺序依次执行,因此需要小心编写顺序,以确保它们按照预期工作。 中间件可以处理请求并返回响应,也可以将请求传递给下一个中间件,以便处理。中间件可以执行许多操作,比如日志记录、异…

    C# 2023年6月3日
    00
  • 彻底弄懂C#中delegate、event、EventHandler、Action、Func的使用和区别

    【目录】 1 委托 2 事件-概念的引出 3 事件-关于异常 4 事件-关于异步 5 委托-Func与Action   1 委托 在.NET中定义“委托”需要用到delegate关键字,它是存有对某个方法的引用的一种引用类型变量,类似于 C 或 C++ 中函数的指针。“委托”主要有两大作用: (1)将方法当作参数传递 (2)方法的一种多态(类似于一个方法模板…

    C# 2023年4月18日
    00
  • C# 获取进程退出代码的实现示例

    C# 获取进程退出代码的实现示例包括以下步骤: 获取进程对象 可以使用Process类来获取指定进程的对象,代码如下: Process process = Process.GetProcessById(processId); 其中,processId为进程的ID号。如果希望通过进程的名称来获取进程对象,可以使用以下代码: Process process = …

    C# 2023年5月31日
    00
  • 字符串优化

    C#字符串优化学习总结 内存区域 我们知道一个由C/C++编译的程序占用的内存分为以下几个部分: 1、栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) : 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于…

    C# 2023年4月22日
    00
  • c# delegate和event的使用说明

    下面是关于”C# delegate和event的使用说明”的完整攻略。 什么是C# delegate? C# delegate是一种类型,该类型可以保存对一个或多个方法的引用并允许在需要时调用这些方法。可以将Delegate看作是函数指针的高级版本。Delegate对象保存的不是方法,而是指向方法的引用。这使得我们可以通过传递委托对象作为参数,从一个方法调用…

    C# 2023年6月7日
    00
  • 编写简易Android天气应用的代码示例

    编写Android天气应用是一个常见的练手项目,可以帮助开发者熟悉Android开发的基本流程和技术。本文将提供一个简易的Android天气应用的代码示例,包括两个示例。 示例1:获取天气数据 要编写一个天气应用,首先需要获取天气数据。可以使用第三方天气API来获取天气数据。以下是一个示例: public class WeatherAPI { private…

    C# 2023年5月15日
    00
  • C#导出Excel的示例详解

    C#导出Excel的示例详解 介绍 在实际的项目中,我们经常需要将数据导出到Excel表格中,以方便查阅和管理。C#作为一门强大的编程语言,在导出Excel方面也有非常不错的表现。本篇文章将详细讲解如何使用C#导出Excel表格。 准备工作 我们需要使用C#自带的OpenXML库来实现Excel的导出。在使用前,需要进行一些准备工作: 引入DocumentF…

    C# 2023年6月7日
    00
  • C#: 引用变量与数值变量的区别

    C#中变量分为引用变量和数值变量,它们的区别在于它们的存储方式和数据类型。 引用变量和数值变量的概念 引用变量指的是具有内存地址的变量,该变量存储的是对象在内存中的地址。引用变量指向对象存储在堆内存中的地址而不是实际的值。当程序使用引用变量时,实际上是通过内存地址来操作堆中的对象。引用变量主要用于引用类型数据,如类、接口、委托等。 数值变量指的是实际的数值,…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部