Код: Выделить всё
Process1()Код: Выделить всё
Process2()См. Диаграмму
Существуют постоянные проблемы с правильной обработкой соединения, отправки/получения сообщений, закрытия и повторного отмены на концепцию 3rd-party. И я хотел бы спросить, как правильно обработать этот сценарий, и если что-то не так с текущей реализацией.
Код: Выделить всё
public async Task Get(CancellationToken cancellationToken)
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
using var clientSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
await _wsService.HandleConnectionAsync(clientSocket, cancellationToken);
}
else
{
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
Код: Выделить всё
public async Task HandleConnectionAsync(WebSocket clientSocket, CancellationToken cancellationToken)
{
using var thirdPartySocket = await _thirdPartyClient.ConnectAsync(cancellationToken);
// Run both directions in parallel
var process1 = Process1Async(clientSocket, thirdPartySocket, cancellationToken);
var process2 = Process2Async(clientSocket, thirdPartySocket, cancellationToken);
await Task.WhenAny(process1, process2); // whichever finishes first
}
Код: Выделить всё
private async Task Process1Async(WebSocket client, WebSocket thirdParty, CancellationToken cancellationToken)
{
var buffer = new byte[4096];
while (!cancellationToken.IsCancellationRequested &&
client.State == WebSocketState.Open &&
thirdParty.State == WebSocketState.Open)
{
WebSocketReceiveResult? result = null;
string? msg = null;
try
{
var messageBuilder = new StringBuilder();
// Read until entire message is received
do
{
result = await client.ReceiveAsync(buffer, cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
await thirdParty.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client closed", cancellationToken);
return; // exit gracefully
}
messageBuilder.Append(Encoding.UTF8.GetString(buffer, 0, result.Count));
} while (!result.EndOfMessage);
msg = messageBuilder.ToString();
}
catch (OperationCanceledException)
{
break;
}
catch (WebSocketException ex)
{
Console.WriteLine($"Process1 WebSocket error: {ex.Message}");
break;
}
catch (Exception ex)
{
Console.WriteLine($"Process1 unexpected error: {ex}");
break;
}
if (!string.IsNullOrEmpty(msg))
{
var transformed = $"[To3rdParty]: {msg}";
var bytes = Encoding.UTF8.GetBytes(transformed);
await thirdParty.SendAsync(bytes, WebSocketMessageType.Text, true, cancellationToken);
}
}
}
private async Task Process2Async(WebSocket client, WebSocket thirdParty, CancellationToken cancellationToken)
{
var buffer = new byte[4096];
while (!cancellationToken.IsCancellationRequested &&
client.State == WebSocketState.Open &&
thirdParty.State == WebSocketState.Open)
{
WebSocketReceiveResult? result = null;
string? msg = null;
try
{
var messageBuilder = new StringBuilder();
// Read until entire message is received
do
{
result = await thirdParty.ReceiveAsync(buffer, cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "3rd party closed", cancellationToken);
return; // exit gracefully
}
messageBuilder.Append(Encoding.UTF8.GetString(buffer, 0, result.Count));
} while (!result.EndOfMessage);
msg = messageBuilder.ToString();
}
catch (OperationCanceledException)
{
break;
}
catch (WebSocketException ex)
{
Console.WriteLine($"Process2 WebSocket error: {ex.Message}");
break;
}
catch (Exception ex)
{
Console.WriteLine($"Process2 unexpected error: {ex}");
break;
}
if (!string.IsNullOrEmpty(msg))
{
var transformed = $"[ToClient]: {msg}";
var bytes = Encoding.UTF8.GetBytes(transformed);
await client.SendAsync(bytes, WebSocketMessageType.Text, true, cancellationToken);
}
}
}
< /code>
Как вы думаете, что отсутствует в текущей реализации? Я делаю плохую практику?>
Подробнее здесь: https://stackoverflow.com/questions/797 ... -between-a
Мобильная версия