У меня есть основное приложение Asp.NET.Startup.Configure()
в основном содержит этот код
app.UseWebSockets();
app.Use(async (httpContext, next) =>
{
// If the request is a WebServerRequest, handle it as such ...
if (httpContext.WebSockets.IsWebSocketRequest)
{
ClientHandler h = new ClientHandler(httpContext);
if (h.IsWebsockOpen)
{
await h.Handle();
}
else
{
httpContext.Response.StatusCode = 400;
}
}
// ... otherwise just hand the request to the next element in chain
else
{
await next();
}
});
Внутри h.Handle()
клиент должен регистрироваться на ClientManager
, который, в свою очередь, многоадресно передает, что новый клиент подключил вот так
public async Task Multicast<T>(List<ClientHandler> l, Msg<T> m)
{
foreach (ClientHandler h in l)
{
if (h.IsWebsockOpen)
{
await h.webSocket.SendAsync(
System.Text.Encoding.UTF8.GetBytes(m.ToString()),
System.Net.WebSockets.WebSocketMessageType.Text,
true,
System.Threading.CancellationToken.None);
}
}
}
Теперь мне интересно, безопасно ли это делать.Я могу представить себе сценарий, когда два клиента соединяются одновременно, в результате чего h.webSocket.SendAsync
вызывается дважды одновременно, что недопустимо, как сказано в
https://docs.microsoft.com/en-us/dotnet/api/system.net.websockets.websocket.sendasync?view=netframework-4.8
Замечания Этооперация не заблокирует.Возвращенный объект Task завершится после отправки данных в WebSocket.
Для каждого объекта WebSocket параллельно поддерживается только одна отправка и один прием.
Обтекание h.webSocket.SendAsync
в lock
-состоянии кажется невозможным из-за ключевого слова await
.
Как я могу сделать мой код безопасным?Связанные вопросы либо не используют WebSockets, либо используют разные платформы, для которых применяются механизмы.