public WebSocketClient( Uri url, WebSocketMessageSender sender = null, ReceiverMemoryConfig receiverConfig = null, ILogger logger = null, string name = "CLIENT", Encoding messageEncoding = null, Func <ClientWebSocket> clientFactory = null) { if (!ValidationUtils.ValidateInput(url)) { throw new ArgumentNullException(nameof(url)); } Url = url; Name = name; _logger = logger; MessageEncoding = messageEncoding ?? Encoding.UTF8; receiverConfig = receiverConfig ?? ReceiverMemoryConfig.Default; //cannot use =?? in unity _memoryPool = new MemoryPool(receiverConfig.InitialMemorySize, receiverConfig.MarginSize, logger); _clientFactory = clientFactory ?? DefaultClientFactory; _webSocketMessageSender = sender?.AsCore() ?? new SingleQueueSenderCore(); _webSocketMessageSender.SetConfig(MessageEncoding, logger, Name); _webSocketMessageSender .ExceptionHappenedInSending .Subscribe(x => { _backgroundExceptionQueue.Enqueue(x); Dispose(); }); }
public WebSocketClient( WebSocket connectedSocket, WebSocketMessageSender sender = null, ReceiverMemoryConfig receiverConfig = null, ILogger logger = null, string name = "CLIENT", Encoding messageEncoding = null) { _socket = connectedSocket ?? throw new ArgumentNullException(nameof(connectedSocket)); Url = null; _clientFactory = null; Name = name; _logger = logger; MessageEncoding = messageEncoding ?? Encoding.UTF8; receiverConfig = receiverConfig ?? ReceiverMemoryConfig.Default; _memoryPool = new MemoryPool(receiverConfig.InitialMemorySize, receiverConfig.MarginSize, logger); _webSocketMessageSender = sender?.AsCore() ?? new SingleQueueSenderCore(); _webSocketMessageSender.SetConfig(MessageEncoding, logger, Name); _webSocketMessageSender .ExceptionHappenedInSending .Subscribe(x => { _backgroundExceptionQueue.Enqueue(x); Dispose(); }); }
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)); }