private static async Task StartWebSocketAsync( TcpClient tcpClient, CancellationTokenSource innerCancellationTokenSource) { //var client = new MessageWebsocketRx(tcpClient) var client = new MessageWebsocketRx(tcpClient, hasTransferTcpSocketLifeCycleOwnership: false) { IgnoreServerCertificateErrors = true, Headers = new Dictionary <string, string> { { "Pragma", "no-cache" }, { "Cache-Control", "no-cache" } }, TlsProtocolType = SslProtocols.Tls12, //ExcludeZeroApplicationDataInPong = true, }; Console.WriteLine("Start"); var websocketConnectionObservable = client.WebsocketConnectWithStatusObservable( uri: new Uri(WebsocketTestServerUrl), hasClientPing: true, clientPingInterval: TimeSpan.FromSeconds(10), clientPingMessage: "ping message"); var disposableConnectionStatus = websocketConnectionObservable .Do(tuple => { Console.ForegroundColor = (int)tuple.state switch { >= 1000 and <= 1999 => ConsoleColor.Magenta, >= 2000 and <= 2999 => ConsoleColor.Green, >= 3000 and <= 3999 => ConsoleColor.Cyan, >= 4000 and <= 4999 => ConsoleColor.DarkYellow, _ => ConsoleColor.Gray, };
internal static async Task <WebsocketService> Create( Func <bool> isSecureConnectionSchemeFunc, Func <object, X509Certificate, X509Chain, SslPolicyErrors, bool> validateServerCertificateFunc, EventLoopScheduler eventLoopScheduler, IObserver <ConnectionStatus> observerConnectionStatus, MessageWebsocketRx messageWebSocketRx) { var tcpConnectionHandler = new TcpConnectionService( isSecureConnectionSchemeFunc: isSecureConnectionSchemeFunc, validateServerCertificateFunc: validateServerCertificateFunc, connectTcpClientFunc: ConnectTcpClient, ReadOneByteFromStream, //readOneByteFunc: (stream, bytes, cts) => RunOnScheduler(ReadOneByteFromStream(stream, bytes, cts), eventLoopScheduler), connectionStatusAction: ConnectionStatusAction, messageWebSocketRx.HasTransferSocketLifeCycleOwnership, tcpClient: messageWebSocketRx.TcpClient); var websocketServices = new WebsocketService( new WebsocketConnectionHandler( tcpConnectionHandler, new WebsocketParserHandler( tcpConnectionHandler), ConnectionStatusAction, (stream, connectionStatusAction) => new WebsocketSenderHandler( tcpConnectionHandler, ConnectionStatusAction, //WriteToStream (stream, bytes, cts) => RunOnScheduler(WriteToStream(stream, bytes, cts), eventLoopScheduler), messageWebSocketRx.ExcludeZeroApplicationDataInPong ) ) ); await Task.CompletedTask; return(websocketServices); void ConnectionStatusAction(ConnectionStatus status, Exception?ex) { if (status is ConnectionStatus.Disconnected) { observerConnectionStatus.OnCompleted(); } if (status is ConnectionStatus.Aborted) { observerConnectionStatus.OnError( ex ?? new WebsocketClientLiteException("Unknown error.")); } observerConnectionStatus.OnNext(status); } async Task <bool> WriteToStream(Stream stream, byte[] byteArray, CancellationToken ct) { await stream.WriteAsync(byteArray, 0, byteArray.Length, ct).ConfigureAwait(false); await stream.FlushAsync().ConfigureAwait(false); return(true); } async Task <int> ReadOneByteFromStream(Stream stream, byte[] byteArray, CancellationToken ct) { try { return(await stream.ReadAsync(byteArray, 0, byteArray.Length, ct).ConfigureAwait(false)); } catch (OperationCanceledException) { return(-1); } } async Task ConnectTcpClient(TcpClient tcpClient, Uri uri) => await tcpClient .ConnectAsync(uri.Host, uri.Port) .ConfigureAwait(false); // Running sends and/or writes on the Event Loop Scheduler serializes them. async Task <T> RunOnScheduler <T>(Task <T> task, IScheduler scheduler) => await task.ToObservable().ObserveOn(scheduler); }