在Winform服务端处理多个WebSocket链接时,可以使用定时器和心跳包来判断客户端是否在线。以下是实现方法:

  1. 创建一个定时器,定时发送心跳包到客户端。

  2. 在每个WebSocket连接中,设置一个心跳包计数器,每次收到心跳包后将计数器重置为0。

  3. 在服务端处理心跳包的代码中,遍历所有连接,检查计数器的值,如果超过一定阈值,则认为该连接已经断开。

示例代码如下:

public class WebSocketServer
{
    private readonly List<WebSocket> _sockets = new List<WebSocket>();
    private readonly Timer _timer;

    public WebSocketServer()
    {
        _timer = new Timer(1000);
        _timer.Elapsed += SendHeartbeat;
        _timer.Enabled = true;
    }

    public async Task AcceptWebSocket(HttpContext context)
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
            _sockets.Add(socket);

            // Set up the heartbeat counter for this socket
            socket.SetHeartbeatCounter(0);

            // Handle the incoming messages for this socket
            await HandleSocket(socket);
        }
        else
        {
            context.Response.StatusCode = 400;
        }
    }

    private async Task HandleSocket(WebSocket socket)
    {
        while (socket.State == WebSocketState.Open)
        {
            var buffer = new byte[1024];
            var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            if (result.MessageType == WebSocketMessageType.Close)
            {
                // Remove the socket from the list
                _sockets.Remove(socket);
                break;
            }
            else if (result.MessageType == WebSocketMessageType.Text)
            {
                // Handle the incoming message
                await HandleMessage(socket, buffer);
            }
            else if (result.MessageType == WebSocketMessageType.Binary)
            {
                // Handle the incoming binary message
                await HandleBinaryMessage(socket, buffer);
            }
            else if (result.MessageType == WebSocketMessageType.Ping)
            {
                // Reset the heartbeat counter
                socket.SetHeartbeatCounter(0);
            }
        }
    }

    private async Task HandleMessage(WebSocket socket, byte[] buffer)
    {
        // Handle the incoming message
    }

    private async Task HandleBinaryMessage(WebSocket socket, byte[] buffer)
    {
        // Handle the incoming binary message
    }

    private void SendHeartbeat(object sender, ElapsedEventArgs e)
    {
        foreach (WebSocket socket in _sockets)
        {
            int counter = socket.GetHeartbeatCounter();
            if (counter >= 3) // If the heartbeat counter exceeds 3, assume the socket is disconnected
            {
                _sockets.Remove(socket);
                break;
            }

            // Send a heartbeat message to the socket
            socket.SendHeartbeat();

            // Increment the heartbeat counter
            socket.SetHeartbeatCounter(counter + 1);
        }
    }
}

// Extension methods for WebSocket
public static class WebSocketExtensions
{
    private const string HeartbeatMessage = "heartbeat";

    public static int GetHeartbeatCounter(this WebSocket socket)
    {
        if (socket.Properties.TryGetValue("HeartbeatCounter", out object value) && value is int counter)
        {
            return counter;
        }
        return 0;
    }

    public static void SetHeartbeatCounter(this WebSocket socket, int counter)
    {
        socket.Properties["HeartbeatCounter"] = counter;
    }

    public static async Task SendHeartbeat(this WebSocket socket)
    {
        var buffer = Encoding.UTF8.GetBytes(HeartbeatMessage);
        await socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
    }
}

在上述代码中,定时器每隔1秒钟发送一次心跳包到所有连接。每个连接都有一个心跳包计数器,收到心跳包后将计数器重置为0。如果计数器超过3,即认为该连接已经断开。在处理心跳包时,发送一个文本类型的心跳包消息到客户端。客户端收到心跳包后,需要回复一个相同的心跳包消息,以重置服务端的心跳包计数器。

winfrom服务端处理多个websocket链接发送心跳包判断是否在线

原文地址: https://www.cveoy.top/t/topic/uxX 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录