使用 WebSocket 在 .NET 8 中实现聊天功能

使用 HTTP 实现近实时通信的技术有很多,如轮询、长轮询、服务器发送事件,甚至 Webhooks。

所有方法都有一个共同的问题:它们仅限于单向通信。

在本文中,我们将探讨 WebSocket(一种构建在 TCP/IP 协议之上的协议,允许双向实时通信),并用它在 .NET 8 中实现一个简单的聊天应用程序。

WebSocket 与服务器发送事件(SSE)

与之前的文章一样,我将把 WebSocket 与最接近的替代品 SSE 进行比较。

相似之处

SSE 和 WebSockets:

  • 使用单个持久的 TCP/IP 连接
  • 所有现代浏览器都支持
  • 允许实时通信

不同点

服务器发送事件使用简单的 HTTP 请求,受限于其请求-响应设计,只能进行单向通信。

WebSocket 是一种建立在 TCP/IP 基础上的双向(全双工)实时通信协议。它使用 HTTP 请求建立连接(握手),然后升级为 WebSocket 连接。

与 SSE 不同,WebSocket 还支持二进制信息。

这使它成为需要双向通信(如聊天应用程序)的绝佳选择。

使用 WebSocket 在 .NET 8 中实现聊天功能
建立 WebSocket 连接

实现 WebSocket 服务器

让我们在 .NET 8 中构建一个简单的 WebSocket 服务器。

首先,我们将设置一个 Web 服务器和所需的依赖项。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ChatService>();
var app = builder.Build();
app.UseWebSockets();

然后,我们添加一个简单的端点,它将检查所需的标头信息,以确定它是否是一个 WebSocket 请求,如果是,则接受它并将其传递给我们的ChatService

app.MapGet("/", async (HttpContext context, ChatService chatService) => 
{ 
    if (context.WebSockets.IsWebSocketRequest) 
    { 
        var webSocket = wait context.WebSockets.AcceptWebSocketAsync(); 
        wait chatService.HandleWebSocketConnection(webSocket); 
    } 
    else 
    { 
        context.Response.StatusCode = 400; 
        wait context.Response.WriteAsync("预期有 WebSocket 请求"); 
    } 
});

在 ChatService 中,我们将处理 WebSocket 连接。它是一个单例服务,可以跟踪所有连接的客户端。

public class ChatService
{
    private readonly List<WebSocket> _sockets = new();
    
    public async Task HandleWebSocketConnection(WebSocket socket)
    {
        _sockets.Add(socket);
        var buffer = new byte[1024 * 2];
        while (socket.State == WebSocketState.Open)
        {
            var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), default);
            if (result.MessageType == WebSocketMessageType.Close)
            {
                await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, default);
                break;
            }
            
            foreach (var s in _sockets)
            {
                await s.SendAsync(buffer[..result.Count], WebSocketMessageType.Text, true, default);
            }
        }
        _sockets.Remove(socket);
    }
}

当 WebSocket 打开时,我们等待下一条消息。如果是 Close 消息,只需关闭连接即可。如果没有,我们读取它并将其写入分配的缓冲区

然后,我们从包含该消息的缓冲区中取出一个片段,发送给所有已连接的客户端。

为了保持简单,我们不会验证消息类型或消息大小,也不会序列化/反序列化为域实体,而这可能是您在实际应用中需要做的事情。

实现 WebSocket 客户端

由于所有浏览器都支持 WebSocket,因此我们将使用 HTML 和 JavaScript 构建客户端。

<div id="messages"></div>
<input id="chatbox" >
<script>
    const socket = new WebSocket('ws://localhost:5007');
    
    socket.onmessage = function (event) {
        const messages = document.getElementById("messages");
        messages.innerHTML += `<p>${event.data}</p>`;
    };

    document.getElementById("chatbox").addEventListener("keyup", function(event) {
        if (event.key === "Enter") {
            socket.send(event.target.value);
            event.target.value = "";
        }
    });
</script>

这段简单的代码会打开一个 WebSocket 连接,并显示类似聊天应用程序的内容。

使用 WebSocket 在 .NET 8 中实现聊天功能

更多用例,请查看GitHub

作者: Roko Kovač

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/38702.html

(0)

相关推荐

发表回复

登录后才能评论