public async Task InvokeAsync(HttpContext context, RequestDelegate next) { try { if (_serverIsRunning) { if (context.Request.Path == "/micro/ws" && context.WebSockets.IsWebSocketRequest) { var socket = await context.WebSockets.AcceptWebSocketAsync(); var completion = new TaskCompletionSource <object>(); var client = new WebSocketClient(socket, _loggerFactory, completion); client.OnClose += (key, websocket) => Clients.TryRemove(key, out _); client.OnReceive += async buffer => { var sender = new WebSocketMessageSender(client.Socket, _messageCodec, _address.Gzip); try { var invokeMessage = await _messageCodec.DecodeAsync <InvokeMessage>(buffer, _address.Gzip); await _listener.OnReceived(sender, invokeMessage); } catch (Exception ex) { _logger.LogError(ex, $"接收消息异常:{ex.Message}"); } }; Clients.TryAdd(client.SocketId, client); _logger.LogInformation($"Socket {client.SocketId}: New connection."); // TaskCompletionSource<> is used to keep the middleware pipeline alive; // SocketProcessingLoop calls TrySetResult upon socket termination _ = Task.Run(() => client.ReceiveAsync(SocketLoopTokenSource.Token).ConfigureAwait(false)); await completion.Task; } } else { context.Response.StatusCode = 409; } } catch (Exception ex) { // HTTP 500 Internal server error context.Response.StatusCode = 500; //Program.ReportException(ex); } finally { // if this middleware didn't handle the request, pass it on if (!context.Response.HasStarted) { await next(context); } } }
protected override async Task <IMicroClient> Create(ServiceAddress address) { var listener = new MessageListener(); var webSocket = new ClientWebSocket(); var uri = new Uri(new Uri(address.ToString()), "/micro/ws"); await webSocket.ConnectAsync(uri, CancellationToken.None); var codec = Provider.GetClientCodec(address.Codec); var sender = new WebSocketMessageSender(webSocket, codec, address.Gzip); var completion = new TaskCompletionSource <object>(); var socketClient = new WebSocketClient(webSocket, LoggerFactory, completion); socketClient.OnReceive += async buffer => { var resultMessage = await codec.DecodeAsync <MessageResult>(buffer, address.Gzip); await listener.OnReceived(sender, resultMessage); }; socketClient.OnClose += (key, socket) => Remove(address); _ = Task.Run(() => socketClient.ReceiveAsync(CancellationToken.None).ConfigureAwait(false)); return(new MicroClient(sender, listener, MicroExecutor, LoggerFactory)); }