在Hanle方法等待客户端的消息
private async Task Handle(WebsocketClient webSocket)
{
WebsocketClientCollection.Add(webSocket);
_logger.LogInformation($"Websocket client added.");
WebSocketReceiveResult result = null;
do
{
var buffer = new byte[1024 * 1];
result = await webSocket.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text && !result.CloseStatus.HasValue)
{
var msgString = Encoding.UTF8.GetString(buffer);
_logger.LogInformation($"Websocket client ReceiveAsync message {msgString}.");
var message = JsonConvert.DeserializeObject<Message>(msgString);
message.SendClientId = webSocket.Id;
MessageRoute(message);
}
}
while (!result.CloseStatus.HasValue);
WebsocketClientCollection.Remove(webSocket);
_logger.LogInformation($"Websocket client closed.");
}
在MessageRoute方法内对客户端的消息进行转发
对客户端的消息定义几个标准的action,对不同的action进行特定的处理,比如加入房间、离开房间、在房间内广播消息等。
private void MessageRoute(Message message)
{
var client = WebsocketClientCollection.Get(message.SendClientId);
switch (message.action)
{
case "join":
client.RoomNo = message.msg;
client.SendMessageAsync($"{message.nick} join room {client.RoomNo} success .");
_logger.LogInformation($"Websocket client {message.SendClientId} join room {client.RoomNo}.");
break;
case "send_to_room":
if (string.IsNullOrEmpty(client.RoomNo))
{
break;
}
var clients = WebsocketClientCollection.GetRoomClients(client.RoomNo);
clients.ForEach(c =>
{
c.SendMessageAsync(message.nick + " : " + message.msg);
});
_logger.LogInformation($"Websocket client {message.SendClientId} send message {message.msg} to room {client.RoomNo}");
break;
case "leave":
var roomNo = client.RoomNo;
client.RoomNo = "";
client.SendMessageAsync($"{message.nick} leave room {roomNo} success .");
_logger.LogInformation($"Websocket client {message.SendClientId} leave room {roomNo}");
break;
default:
break;
}
}
新建WebsocketClientCollection管理类
这个类是个容器,用来存放所有的websocket链接,便于统一管理。
public class WebsocketClientCollection
{
private static List<WebsocketClient> _clients = new List<WebsocketClient>();
public static void Add(WebsocketClient client)
{
_clients.Add(client);
}
public static void Remove(WebsocketClient client)
{
_clients.Remove(client);
}
public static WebsocketClient Get(string clientId)
{
var client = _clients.FirstOrDefault(c=>c.Id == clientId);
return client;
}
public static List<WebsocketClient> GetRoomClients(string roomNo)
{
var client = _clients.Where(c => c.RoomNo == roomNo);
return client.ToList();
}
}
在Startup中使用中间件








