Как правильно обрабатывать WebSocket API, который действует как средний уровень между клиентом (Frontend) и еще одним APC#

Место общения программистов C#
Ответить
Anonymous
 Как правильно обрабатывать WebSocket API, который действует как средний уровень между клиентом (Frontend) и еще одним AP

Сообщение Anonymous »

У нас есть API, который действует как средний слой между клиентом (Frontend) и API 3-й стороны. Что касается своей конечной точки WebSocket, в настоящее время он принимает сообщение (JSON) и отмену от клиента, обновляет протокол до WebSocket и выполняет соответствующий метод службы.

Код: Выделить всё

Process1()
- прослушивает сообщения от клиента (Frontend) и преобразует их перед отправкой в ​​API 3 -й стороны.

Код: Выделить всё

Process2()
-Слушает сообщения из API 3-й стороны и преобразует его перед отправкой к клиенту (Frontend).
См. Диаграмму
Существуют постоянные проблемы с правильной обработкой соединения, отправки/получения сообщений, закрытия и повторного отмены на концепцию 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
}
метод процесса1:

Код: Выделить всё

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);
}
}
}
метод процесса2:
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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»