/// <summary> /// Connects to the WebSocket server. /// </summary> /// <param name="uri">The URI of the WebSocket server.</param> /// <param name="customHeaders">Custom headers to send with the request.</param> /// <returns></returns> public override async Task ConnectAsync(Uri uri, IReadOnlyDictionary <string, string> customHeaders = null) { SocketMessageQueue = new ConcurrentQueue <string>(); TokenSource = new CancellationTokenSource(); StreamDecompressor?.Dispose(); CompressedStream?.Dispose(); DecompressedStream?.Dispose(); DecompressedStream = new MemoryStream(); CompressedStream = new MemoryStream(); StreamDecompressor = new DeflateStream(CompressedStream, CompressionMode.Decompress); Socket = new ClientWebSocket(); Socket.Options.KeepAliveInterval = TimeSpan.FromSeconds(20); if (Proxy != null) // because mono doesn't implement this properly { Socket.Options.Proxy = Proxy; } if (customHeaders != null) { foreach (var kvp in customHeaders) { Socket.Options.SetRequestHeader(kvp.Key, kvp.Value); } } await Socket.ConnectAsync(uri, Token).ConfigureAwait(false); await OnConnectedAsync().ConfigureAwait(false); WsListener = Task.Run(ListenAsync, Token); }
/// <summary> /// Disposes this socket client. /// </summary> public virtual void Dispose() { StreamDecompressor?.Dispose(); CompressedStream?.Dispose(); DecompressedStream?.Dispose(); }
/// <summary> /// Connects to the WebSocket server. /// </summary> /// <param name="uri">The URI of the WebSocket server.</param> /// <param name="customHeaders">Custom headers to send with the request.</param> /// <returns></returns> public override Task ConnectAsync(Uri uri, IReadOnlyDictionary <string, string> customHeaders = null) { StreamDecompressor?.Dispose(); CompressedStream?.Dispose(); DecompressedStream?.Dispose(); DecompressedStream = new MemoryStream(); CompressedStream = new MemoryStream(); StreamDecompressor = new DeflateStream(CompressedStream, CompressionMode.Decompress); _socket = new ws4net.WebSocket(uri.ToString(), customHeaderItems: customHeaders?.ToList()); if (Proxy != null) // f**k this, I ain't working with that shit { throw new NotImplementedException("Proxies are not supported on non-Microsoft WebSocket client implementations."); } _socket.Opened += HandlerOpen; _socket.Closed += HandlerClose; _socket.MessageReceived += HandlerMessage; _socket.DataReceived += HandlerData; _socket.Error += _socket_Error; _socket.Open(); return(Task.FromResult <BaseWebSocketClient>(this)); void HandlerOpen(object sender, s.EventArgs e) => _connect.InvokeAsync().ConfigureAwait(false).GetAwaiter().GetResult(); void HandlerClose(object sender, s.EventArgs e) { if (e is ws4net.ClosedEventArgs ea) { _disconnect.InvokeAsync(new SocketCloseEventArgs(null) { CloseCode = ea.Code, CloseMessage = ea.Reason }).ConfigureAwait(false).GetAwaiter().GetResult(); } else { _disconnect.InvokeAsync(new SocketCloseEventArgs(null) { CloseCode = -1, CloseMessage = "unknown" }).ConfigureAwait(false).GetAwaiter().GetResult(); } } void HandlerMessage(object sender, ws4net.MessageReceivedEventArgs e) { _message.InvokeAsync(new SocketMessageEventArgs { Message = e.Message }).ConfigureAwait(false).GetAwaiter().GetResult(); } void HandlerData(object sender, ws4net.DataReceivedEventArgs e) { string msg; if (e.Data[0] == 0x78) { CompressedStream.Write(e.Data, 2, e.Data.Length - 2); } else { CompressedStream.Write(e.Data, 0, e.Data.Length); } CompressedStream.Flush(); CompressedStream.Position = 0; // partial credit to FiniteReality // overall idea is his // I tuned the finer details // -Emzi var sfix = BitConverter.ToUInt16(e.Data, e.Data.Length - 2); if (sfix != ZLIB_STREAM_SUFFIX) { using (var zlib = new DeflateStream(CompressedStream, CompressionMode.Decompress, true)) zlib.CopyTo(DecompressedStream); } else { StreamDecompressor.CopyTo(DecompressedStream); } msg = UTF8.GetString(DecompressedStream.ToArray(), 0, (int)DecompressedStream.Length); DecompressedStream.Position = 0; DecompressedStream.SetLength(0); CompressedStream.Position = 0; CompressedStream.SetLength(0); _message.InvokeAsync(new SocketMessageEventArgs { Message = msg }).ConfigureAwait(false).GetAwaiter().GetResult(); } }