private async System.Threading.Tasks.Task ProcessRequestAsync(System.Net.HttpListenerContext HttpListenerContext, System.Threading.CancellationToken CancellationToken = default) { System.Net.WebSockets.WebSocketContext WebSocketContext = null; try { WebSocketContext = await HttpListenerContext.AcceptWebSocketAsync(null); } catch { HttpListenerContext.Response.StatusCode = 500; HttpListenerContext.Response.Close(); return; } SoftmakeAll.SDK.Communication.ServerWebSocket.ConnectionProperties ConnectionProperties = new SoftmakeAll.SDK.Communication.ServerWebSocket.ConnectionProperties(WebSocketContext); lock (this.SyncRoot) this.ActiveConnections.Add(ConnectionProperties.ConnectionID, ConnectionProperties); this.ClientConnected?.Invoke(ConnectionProperties.ConnectionID); const System.Int16 BufferSize = 512; System.Net.WebSockets.WebSocketReceiveResult Result; do { System.Collections.Generic.IEnumerable <System.Byte> Data = new System.Byte[] { }; do { System.Byte[] Buffer = new System.Byte[BufferSize]; Result = await WebSocketContext.WebSocket.ReceiveAsync(new System.ArraySegment <System.Byte>(Buffer), CancellationToken); if (Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Text) { Data = Data.Concat(Buffer); } }while (!(Result.EndOfMessage)); if ((Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Text) && (this.ReceiveMessageFunc != null)) { await this.ReplyAsync(ConnectionProperties, System.Text.Encoding.UTF8.GetString(Data.SkipLast(BufferSize - Result.Count).ToArray()), CancellationToken); } else if (Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) { await this.DropConnectionAsync(ConnectionProperties, true, CancellationToken); } }while (WebSocketContext.WebSocket.State == System.Net.WebSockets.WebSocketState.Open); }
public async System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken CancellationToken = default) { if (this.WebSocket == null) { this.WebSocket = new System.Net.WebSockets.ClientWebSocket(); foreach (System.Collections.Generic.KeyValuePair <System.String, System.String> Header in this.Headers) { WebSocket.Options.SetRequestHeader(Header.Key, Header.Value); } if (this.PingInterval != System.TimeSpan.Zero) { WebSocket.Options.SetRequestHeader("pingInterval", this.PingInterval.TotalMilliseconds.ToString()); } } switch (this.WebSocket.State) { case System.Net.WebSockets.WebSocketState.Connecting: case System.Net.WebSockets.WebSocketState.Open: return; default: break; } if (!(this._IsReconnection)) { this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Connecting; } else { this.Reconnecting?.Invoke(null); this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Reconnecting; } try { await this.WebSocket.ConnectAsync(new System.Uri(this.URL), CancellationToken); } catch { this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Disconnected; throw; } if (this.WebSocket.State != System.Net.WebSockets.WebSocketState.Open) { this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Disconnected; return; } this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Connected; if (this._IsReconnection) { this.Reconnected?.Invoke(null); } _ = System.Threading.Tasks.Task.Run(async() => { const System.Int16 BufferSize = 512; System.Net.WebSockets.WebSocketReceiveResult Result; do { System.Collections.Generic.IEnumerable <System.Byte> Data = new System.Byte[] { }; do { System.Byte[] Buffer = new System.Byte[BufferSize]; Result = await this.WebSocket.ReceiveAsync(new System.ArraySegment <System.Byte>(Buffer), System.Threading.CancellationToken.None); if (Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Text) { Data = Data.Concat(Buffer); } }while (!(Result.EndOfMessage)); if ((Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Text) && (this.ReceiveMessageAction != null)) { System.String Message = System.Text.Encoding.UTF8.GetString(Data.SkipLast(BufferSize - Result.Count).ToArray()); if (!(Message.StartsWith("{\"pong\":"))) { this.ReceiveMessageAction?.Invoke(Message); } else { System.Int64 ServerUnixTime = Message.ToJsonElement().GetInt64("pong"); this._Latency = ServerUnixTime > 0 ? System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - ServerUnixTime : 0; /* #if DEBUG * System.Console.WriteLine(Message); // Debug Pong Messages #endif */ } } else if (Result.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) { this.State = SoftmakeAll.SDK.Communication.ClientWebSocket.ConnectionStates.Disconnected; this.Closed?.Invoke(Result.CloseStatus == System.Net.WebSockets.WebSocketCloseStatus.NormalClosure || Result.CloseStatusDescription == null ? null : new System.Exception(Result.CloseStatusDescription)); } }while (this.WebSocket.State == System.Net.WebSockets.WebSocketState.Open); }); if ((!(this._IsReconnection)) && (this.PingInterval != System.TimeSpan.Zero)) { this._ReconnectionTimer = new System.Threading.Timer(this.Reconnect, null, System.TimeSpan.Zero, this.PingInterval); } this._IsReconnection = true; }