public async Task RunShouldWriteBytesToWebSocket( int sequenceNumber, byte[] bytes, [Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayService gateway, [Frozen, Substitute] IChannel <GatewayMessage> channel, [Frozen, Substitute] ISerializer serializer, [Frozen, Substitute] IGatewayUtilsFactory factory, [Target] DefaultGatewayTxWorker worker ) { var message = new GatewayMessage { SequenceNumber = sequenceNumber }; var cancellationToken = new CancellationToken(false); serializer.SerializeToBytes(Any <GatewayMessage>()).Returns(bytes); channel.Read(Any <CancellationToken>()).Returns(new ValueTask <GatewayMessage>(message)); clientWebSocket.State.Returns(WebSocketState.Open); await worker.Start(gateway, clientWebSocket); await worker.Run(cancellationToken); await clientWebSocket.Received().Send(Is <ArraySegment <byte> >(bytes), Is(WebSocketMessageType.Text), Is(true), Is(cancellationToken)); }
public override async Task ConnectAsync() { await base.ConnectAsync(); if (_webSocketTransport != null) { _webSocketTransport.OnTextReceived -= OnTextReceived; _webSocketTransport.OnBinaryReceived -= OnBinaryReceived; _webSocketTransport.OnAborted -= OnAborted; _webSocketTransport.Dispose(); } Uri uri = UriConverter.GetServerUri(true, ServerUri, EIO, Options.Path, Options.Query); _clientWebSocket = ClientWebSocketProvider(); if (Options.ExtraHeaders != null) { foreach (var item in Options.ExtraHeaders) { _clientWebSocket.SetRequestHeader(item.Key, item.Value); } } _webSocketTransport = new WebSocketTransport(_clientWebSocket, EIO) { ConnectionTimeout = Options.ConnectionTimeout }; _webSocketTransport.OnTextReceived = OnTextReceived; _webSocketTransport.OnBinaryReceived = OnBinaryReceived; _webSocketTransport.OnAborted = OnAborted; Debug.WriteLine($"[Websocket] Connecting"); await _webSocketTransport.ConnectAsync(uri).ConfigureAwait(false); Debug.WriteLine($"[Websocket] Connected"); }
public async Task RunShouldReadFromChannelIfWaitToReadReturnsTrue( int sequenceNumber, [Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayService gateway, [Frozen, Substitute] IChannel <GatewayMessage> channel, [Frozen, Substitute] IGatewayUtilsFactory factory, [Target] DefaultGatewayTxWorker worker ) { var message = new GatewayMessage { SequenceNumber = sequenceNumber }; var cancellationToken = new CancellationToken(false); channel.Read(Any <CancellationToken>()).Returns(new ValueTask <GatewayMessage>(message)); clientWebSocket.State.Returns(WebSocketState.Open); await worker.Start(gateway, clientWebSocket); await worker.Run(cancellationToken); await channel.Received().WaitToRead(Is(cancellationToken)); await channel.Received().Read(Is(cancellationToken)); }
public async Task RunShouldWaitUntilTheWebSocketIsOpen( int sequenceNumber, [Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayService gateway, [Frozen, Substitute] IChannel <GatewayMessage> channel, [Frozen, Substitute] IGatewayUtilsFactory factory, [Target] DefaultGatewayTxWorker worker ) { var tries = 0; var message = new GatewayMessage { SequenceNumber = sequenceNumber }; var cancellationToken = new CancellationToken(false); clientWebSocket.State.Returns(WebSocketState.Connecting); channel.Read(Any <CancellationToken>()).Returns(new ValueTask <GatewayMessage>(message)); channel.WaitToRead(Any <CancellationToken>()).Returns(true); factory.CreateDelay(Any <uint>(), Any <CancellationToken>()).Returns(async x => { if (++tries == 2) { clientWebSocket.State.Returns(WebSocketState.Open); } await Task.CompletedTask; }); await worker.Start(gateway, clientWebSocket); await worker.Run(cancellationToken); await factory.Received(2).CreateDelay(100, Is(cancellationToken)); }
async void HandleRequest(string requestName, IClientWebSocket clientWebSocket) { try { if (this.streamRequestHandlerProvider.TryGetHandler(requestName, out IStreamRequestHandler handler)) { Events.HandlerFound(requestName); await handler.Handle(clientWebSocket, this.cts.Token); await this.CloseWebSocketConnection(requestName, clientWebSocket, WebSocketCloseStatus.NormalClosure, string.Empty); } else { Events.NoHandlerFound(requestName); await this.CloseWebSocketConnection(requestName, clientWebSocket, WebSocketCloseStatus.InvalidPayloadData, $"Unknown request name - {requestName}"); } Events.RequestCompleted(requestName); } catch (Exception e) { Events.ErrorHandlingRequest(requestName, e); } finally { this.streamLock.Release(); } }
//public WebSocketTransport(IClientWebSocket ws, SocketIOOptions options, IJsonSerializer jsonSerializer, ILogger logger) // : base(options, jsonSerializer, logger) public WebSocketTransport(IClientWebSocket ws, SocketIOOptions options, IJsonSerializer jsonSerializer) : base(options, jsonSerializer) { _ws = ws; _sendLock = new SemaphoreSlim(1, 1); _ws.TextObservable.Subscribe(this); _ws.BytesObservable.Subscribe(this); }
/*/ Constructors /*/ /// <summary> /// Initializes a new instance of the <see cref="SlackClient"/> class. /// </summary> /// <param name="clientWebSocket">Client web socket.</param> /// <param name="logManager">Log manager.</param> public SlackClient(IClientWebSocket clientWebSocket, ILogManager?logManager = null) { this.webSocket = clientWebSocket ?? throw new ArgumentNullException(nameof(clientWebSocket)); this.logManager = logManager; this.log = this.logManager?.GetLogger(typeof(SlackClient)); this.emptyStringContent = new StringContent(string.Empty); }
private void ResetState() { socket?.Abort(); socket = null; receiveCancellationToken?.Cancel(); receiveCancellationToken = null; sendCancellationToken?.Cancel(); sendCancellationToken = null; }
public async Task UnSubscribe(IOrderbook market, IClientWebSocket client) { if (client.State == WebSocketState.Open) { await Client.SendAsync( new ArraySegment <byte>(Encoding.ASCII.GetBytes($"{{\"method\": \"unsubscribeOrderbook\",\"params\": {{ \"symbol\": \"{market.Symbol}\" }} }}")), WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false); } }
public async Task UnSubscribe(IOrderbook market, IClientWebSocket client) { if (client.State == WebSocketState.Open) { await Client.SendAsync(new ArraySegment <byte>( Encoding.ASCII.GetBytes($"{{\"sub\": \"market.{market.Symbol.ToLower()}.mbp.150\",\n \"id\": \"id{ID}\"\n }}") ), WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false); } }
public OrderbookListener(ILogger <OrderbookListener> logger, IClientWebSocket client, IExchange exch, int id) { _logger = logger; Client = client; Exchange = exch; ID = id; OrderbookType = Exchange.OrderbookType; Client.Exchange = Exchange; }
public async Task StartShouldStartTheTxWorker( [Frozen, Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayTxWorker txWorker, [Target] DefaultGatewayService gateway ) { await gateway.StartAsync(); await txWorker.Received().Start(Is(gateway), Is(clientWebSocket)); }
public bool RegisterClient(string id, IClientWebSocket clientWebSocket) { if (!clientWebSockets.ContainsKey(id)) { clientWebSockets.Add(id, clientWebSocket); return(true); } return(false); }
/// <inheritdoc /> public async Task Start(IGatewayService gateway, IClientWebSocket webSocket) { IsRunning = true; this.webSocket = webSocket; timer = timerFactory.CreateTimer(Run, 0, WorkerThreadName); timer.StopOnException = true; timer.OnUnexpectedStop = () => gateway.Restart(); await timer.Start(); }
public WebSocketTransport(IClientWebSocket ws, int eio) { _eio = eio; _ws = ws; ReceiveChunkSize = 1024 * 8; SendChunkSize = 1024 * 8; ConnectionTimeout = TimeSpan.FromSeconds(10); ReceiveWait = TimeSpan.FromSeconds(1); _listenCancellation = new CancellationTokenSource(); _sendLock = new SemaphoreSlim(1, 1); }
/// <summary> /// Replaces the socket. /// </summary> /// <param name="socket">The socket.</param> private void ReplaceSocket(IClientWebSocket socket) { var previousSocket = _currentWebSocket; _currentWebSocket = socket; if (previousSocket != null) { previousSocket.Dispose(); } }
private async Task HandleOutgoingDataAsync(IClientWebSocket clientWebSocket, Stream localStream, CancellationToken cancellationToken) { var buffer = new byte[bufferSize]; while (localStream.CanRead) { var receiveCount = await localStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); await clientWebSocket.SendAsync(new ArraySegment <byte>(buffer, 0, receiveCount), WebSocketMessageType.Binary, true, cancellationToken).ConfigureAwait(false); } }
async Task CloseWebSocketConnection(string requestName, IClientWebSocket clientWebSocket, WebSocketCloseStatus webSocketCloseStatus, string message) { try { await clientWebSocket.CloseAsync(webSocketCloseStatus, message, this.cts.Token); } catch (Exception ex) { Events.ErrorClosingWebSocket(requestName, ex); } }
public async Task StartShouldCreateTimer( [Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayService gateway, [Frozen, Substitute] ITimerFactory timerFactory, [Target] DefaultGatewayTxWorker txWorker ) { await txWorker.Start(gateway, clientWebSocket); timerFactory.Received().CreateTimer(Is((AsyncTimerCallback)txWorker.Run), Is(0), Is("Gateway TX")); }
public async Task StartShouldStartTheWorkerThread( [Substitute] IClientWebSocket clientWebSocket, [Frozen, Substitute] IGatewayService gateway, [Frozen, Substitute] ITimer timer, [Target] DefaultGatewayTxWorker txWorker ) { await txWorker.Start(gateway, clientWebSocket); await timer.Received().Start(); }
public async Task StopShouldAbortTheWebSocket( [Frozen, Substitute] IClientWebSocket clientWebSocket, [Target] DefaultGatewayService gateway ) { await gateway.StartAsync(); await gateway.StopAsync(); clientWebSocket.Received().Abort(); }
private async Task HandleIncomingDataAsync(IClientWebSocket clientWebSocket, Stream localStream, CancellationToken cancellationToken) { var buffer = new byte[bufferSize]; while (clientWebSocket.State == WebSocketState.Open) { var receiveResult = await clientWebSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false); await localStream.WriteAsync(buffer, 0, receiveResult.Count, cancellationToken).ConfigureAwait(false); } }
public async Task Handle(IClientWebSocket clientWebSocket, CancellationToken cancellationToken) { try { LogsStreamRequest streamRequest = await this.ReadLogsStreamingRequest(clientWebSocket, cancellationToken); Events.RequestData(streamRequest); if (ExpectedSchemaVersion.CompareMajorVersion(streamRequest.SchemaVersion, "logs stream request schema") != 0) { Events.MismatchedMinorVersions(streamRequest.SchemaVersion, ExpectedSchemaVersion); } var socketCancellationTokenSource = new CancellationTokenSource(); Task ProcessLogsFrame(ArraySegment <byte> bytes) { if (clientWebSocket.State != WebSocketState.Open) { Events.WebSocketNotOpen(streamRequest, clientWebSocket.State); socketCancellationTokenSource.Cancel(); return(Task.CompletedTask); } else { return(clientWebSocket.SendAsync(bytes, WebSocketMessageType.Binary, true, cancellationToken)); } } ILogsRequestToOptionsMapper requestToOptionsMapper = new LogsRequestToOptionsMapper( this.runtimeInfoProvider, streamRequest.Encoding, streamRequest.ContentType, LogOutputFraming.SimpleLength, Option.None <LogsOutputGroupingConfig>(), true); IList <(string id, ModuleLogOptions logOptions)> logOptionsList = await requestToOptionsMapper.MapToLogOptions(streamRequest.Items, cancellationToken); using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, socketCancellationTokenSource.Token)) { await this.logsProvider.GetLogsStream(logOptionsList, ProcessLogsFrame, linkedCts.Token); } Events.StreamingCompleted(streamRequest); } catch (Exception e) { Events.ErrorHandlingRequest(e); } }
async Task <LogsStreamRequest> ReadLogsStreamingRequest(IClientWebSocket clientWebSocket, CancellationToken cancellationToken) { // Max size of the request can be 8k var buf = new byte[MaxLogRequestSizeBytes]; var arrSeg = new ArraySegment <byte>(buf); WebSocketReceiveResult result = await clientWebSocket.ReceiveAsync(arrSeg, cancellationToken); if (result.Count > 0) { string jsonString = Encoding.UTF8.GetString(buf, 0, result.Count); return(jsonString.FromJson <LogsStreamRequest>()); } throw new InvalidOperationException("Did not receive logs request from server"); }
/// <summary> /// /// </summary> /// <param name="clientWebSocket"></param> /// <param name="bufferSize"></param> /// <param name="cancellationToken"></param> public ClientWebSocketText(IClientWebSocket clientWebSocket, int bufferSize = 1024, CancellationToken cancellationToken = default(CancellationToken)) { if (clientWebSocket == null) { throw new ArgumentNullException(nameof(clientWebSocket)); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferSize), @"Receive buffer size should be greater than zero"); } _clientWebSocket = clientWebSocket; _bufferSize = bufferSize; _cancellationToken = cancellationToken; _lazyReceiveContext = new Lazy <BufferingContext>(() => new BufferingContextShared(bufferSize), LazyThreadSafetyMode.None); }
/*/ Constructors /*/ /// <summary> /// Initializes a new instance of the <see cref="DiscordClient"/> class. /// </summary> /// <param name="clientWebSocket">Client web socket.</param> /// <param name="httpClient">Http client.</param> /// <param name="logManager">Log Manager.</param> public DiscordClient( IClientWebSocket clientWebSocket, IHttpClient httpClient, ILogManager?logManager = null) { this.httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); this.socket = clientWebSocket ?? throw new ArgumentNullException(nameof(clientWebSocket)); this.logManager = logManager; this.cancelToken = new CancellationToken(false); this.heartbeatTimer = new Timer( this.OnHeartbeatInterval, null, HeartbeatIntervalDefault, HeartbeatIntervalDefault); this.log = this.logManager?.GetLogger(typeof(DiscordClient)); }
private void ConnectWebsocket() { Console.WriteLine("About to connect to main socket at " + webSocketLocation); this.websocket = new WebSocket4NetSocketClient(); this.websocket.MessageReceived += this.WebsocketMessageReceived; this.websocket.Connect(webSocketLocation); Task.Factory.StartNew(this.WaitForSocketToConnect); var socketConnected = this.socketConnectedEvent.WaitOne(TimeSpan.FromSeconds(3)); if (!socketConnected) { throw new WebSocketCouldNotConnectException(); } }
internal async Task RejectAsync(Uri rendezvousUri) { IClientWebSocket clientWebSocket = null; try { if (this.Response.StatusCode == HttpStatusCode.Continue) { this.Response.StatusCode = HttpStatusCode.BadRequest; this.Response.StatusDescription = "Rejected by user code"; } // Add the status code/description to the URI query string int requiredCapacity = rendezvousUri.OriginalString.Length + 50 + this.Response.StatusDescription.Length; var stringBuilder = new StringBuilder(rendezvousUri.OriginalString, requiredCapacity); stringBuilder.AppendFormat("&{0}={1}", HybridConnectionConstants.StatusCode, (int)this.Response.StatusCode); stringBuilder.AppendFormat("&{0}={1}", HybridConnectionConstants.StatusDescription, WebUtility.UrlEncode(this.Response.StatusDescription)); Uri rejectUri = new Uri(stringBuilder.ToString()); clientWebSocket = this.CreateWebSocket(); using (var cancelSource = new CancellationTokenSource(AcceptTimeout)) { await clientWebSocket.ConnectAsync(rejectUri, cancelSource.Token).ConfigureAwait(false); } } catch (Exception e) when(!Fx.IsFatal(e)) { WebException webException; HttpWebResponse httpWebResponse; if (e is WebSocketException && (webException = e.InnerException as WebException) != null && (httpWebResponse = webException.Response as HttpWebResponse) != null && httpWebResponse.StatusCode == HttpStatusCode.Gone) { // status code of "Gone" is expected when rejecting a client request return; } RelayEventSource.Log.HandledExceptionAsWarning(this, e); } finally { clientWebSocket?.WebSocket?.Abort(); } }
public async Task RunShouldReceiveChunksFromTheWebSocket( [Frozen, Options] IOptions <GatewayOptions> options, [Frozen, Substitute] IClientWebSocket webSocket, [Frozen, Substitute] IGatewayRxWorker rxWorker, [Target] DefaultGatewayService gateway ) { var cancellationToken = new CancellationToken(false); webSocket.Receive(Any <Memory <byte> >(), Any <CancellationToken>()).Returns(x => new ValueWebSocketReceiveResult(0, WebSocketMessageType.Text, true)); await gateway.StartAsync(); await gateway.Run(cancellationToken); await webSocket.Received().Receive(Any <Memory <byte> >(), Is(cancellationToken)); }
public async Task RunShouldNotConnectToTheWebSocketServerIfAlreadyConnected( [Frozen, Options] IOptions <GatewayOptions> options, [Frozen, Substitute] IClientWebSocket webSocket, [Frozen, Substitute] IGatewayRxWorker rxWorker, [Target] DefaultGatewayService gateway ) { var cancellationToken = new CancellationToken(false); webSocket.State.Returns(WebSocketState.Open); webSocket.Receive(Any <Memory <byte> >(), Any <CancellationToken>()).Returns(x => new ValueWebSocketReceiveResult(0, WebSocketMessageType.Text, true)); await gateway.StartAsync(); await gateway.Run(cancellationToken); await webSocket.DidNotReceive().Connect(Is(options.Value.Uri), Is(cancellationToken)); }