winfrom服务端处理多个websocket链接发送心跳包判断是否在线
在Winform服务端处理多个WebSocket链接时,可以使用定时器和心跳包来判断客户端是否在线。以下是实现方法:
-
创建一个定时器,定时发送心跳包到客户端。
-
在每个WebSocket连接中,设置一个心跳包计数器,每次收到心跳包后将计数器重置为0。
-
在服务端处理心跳包的代码中,遍历所有连接,检查计数器的值,如果超过一定阈值,则认为该连接已经断开。
示例代码如下:
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,即认为该连接已经断开。在处理心跳包时,发送一个文本类型的心跳包消息到客户端。客户端收到心跳包后,需要回复一个相同的心跳包消息,以重置服务端的心跳包计数器。
原文地址: https://www.cveoy.top/t/topic/uxX 著作权归作者所有。请勿转载和采集!