static int __CreateInstance(RealStatePtr L) { try { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); if (LuaAPI.lua_gettop(L) == 3 && translator.Assignable <System.Net.WebSockets.HttpListenerWebSocketContext>(L, 2) && translator.Assignable <DCET.Model.AService>(L, 3)) { System.Net.WebSockets.HttpListenerWebSocketContext _webSocketContext = (System.Net.WebSockets.HttpListenerWebSocketContext)translator.GetObject(L, 2, typeof(System.Net.WebSockets.HttpListenerWebSocketContext)); DCET.Model.AService _service = (DCET.Model.AService)translator.GetObject(L, 3, typeof(DCET.Model.AService)); DCET.Model.WChannel gen_ret = new DCET.Model.WChannel(_webSocketContext, _service); translator.Push(L, gen_ret); return(1); } if (LuaAPI.lua_gettop(L) == 3 && translator.Assignable <System.Net.WebSockets.WebSocket>(L, 2) && translator.Assignable <DCET.Model.AService>(L, 3)) { System.Net.WebSockets.WebSocket _webSocket = (System.Net.WebSockets.WebSocket)translator.GetObject(L, 2, typeof(System.Net.WebSockets.WebSocket)); DCET.Model.AService _service = (DCET.Model.AService)translator.GetObject(L, 3, typeof(DCET.Model.AService)); DCET.Model.WChannel gen_ret = new DCET.Model.WChannel(_webSocket, _service); translator.Push(L, gen_ret); return(1); } } catch (System.Exception gen_e) { return(LuaAPI.luaL_error(L, "c# exception:" + gen_e)); } return(LuaAPI.luaL_error(L, "invalid arguments to DCET.Model.WChannel constructor!")); }
public WebSocket(System.Net.WebSockets.WebSocket socket, int bufferSize = 8192) { this.Base = socket; this.bufferSize = bufferSize; new Thread(Receive).Start(); }
//创建链接 internal async Task Accept <T>(HttpContext context, Func <Task> n) where T : WebSocketBehavior, new() { try { //是websocket请求才进来 if (context.WebSockets.IsWebSocketRequest) { //执行接收 System.Net.WebSockets.WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); T session = new T { Socket = socket }; session.SetCancelToken(context.RequestAborted); session.BufferSize = BufferSize; session.Context = context; Sessions.Add(session); session.OnOpen(); //执行监听 await session.EchoLoop(context.RequestAborted); } } catch (Exception ex) { Common.LogRecord.Debug("Accept", ex.Message); //throw ex; } }
public async Task Middleware(HttpContext context, Func <Task> next) { if (context.WebSockets.IsWebSocketRequest) { _logger.LogTrace("Web socket connection opened."); #pragma warning disable 4014 //We deliberatly want to run the services without waiting so we can deal with the next request while this one is being handled. switch (context.Request.Path) { case "/toolbar": _logger.LogTrace("Routing connection to logs websocket service."); System.Net.WebSockets.WebSocket webSocketLog = await context.WebSockets.AcceptWebSocketAsync(); var service = ServiceProviderManager.ServiceProvider.GetService <IToolbarSocketService>(); await service.AttachService(context, webSocketLog); break; default: _logger.LogTrace($"Requested service route {context.Request.Path} was not found."); context.Response.StatusCode = (int)HttpStatusCode.NotFound; break; } #pragma warning restore 4014 } else { context.Response.StatusCode = (int)HttpStatusCode.UpgradeRequired; } }
/// <summary>从队列消费消息并推送到WebSocket客户端</summary> /// <param name="socket"></param> /// <param name="queue"></param> /// <param name="source"></param> /// <returns></returns> public static async Task ConsumeAndPushAsync(this System.Net.WebSockets.WebSocket socket, IProducerConsumer <String> queue, CancellationTokenSource source) { var token = source.Token; //var queue = _queue.GetQueue<String>($"cmd:{node.Code}"); try { while (!token.IsCancellationRequested && socket.State == System.Net.WebSockets.WebSocketState.Open) { var msg = await queue.TakeOneAsync(30_000); if (msg != null) { await socket.SendAsync(new ArraySegment <Byte>(msg.GetBytes()), System.Net.WebSockets.WebSocketMessageType.Text, true, token); } else { await Task.Delay(100, token); } } } catch (Exception ex) { XTrace.WriteException(ex); } finally { //if (token.GetValue("_source") is CancellationTokenSource source) source.Cancel(); source.Cancel(); } }
// ------------------------------------------------------------------------------------ public System.Threading.Tasks.Task SendAsync( System.Net.WebSockets.WebSocket WS, System.Threading.CancellationTokenSource cts_shutdown) { return(WS.SendAsync( new ArraySegment <byte>(m_ary_buf, 0, m_idx_byte) , System.Net.WebSockets.WebSocketMessageType.Binary, true // endOfMessage , cts_shutdown.Token)); }
public static async Task <System.Net.WebSockets.WebSocket> AcceptWebSocketRequestAsync(this HttpContext context, WebSocketHandler handler) { System.Net.WebSockets.WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); await handler.ProcessWebSocketRequestAsync(socket); return(socket); }
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.1 private static async System.Threading.Tasks.Task GetTableAsync( Microsoft.AspNetCore.Http.HttpContext context , System.Net.WebSockets.WebSocket webSocket) { WebSocketTextWriter wtw = new WebSocketTextWriter(webSocket); byte[] buffer = new byte[1024 * 4]; System.Net.WebSockets.WebSocketReceiveResult result = await webSocket.ReceiveAsync( new System.ArraySegment <byte>(buffer) , System.Threading.CancellationToken.None ); SqlService service = (SqlService)context.RequestServices.GetService(typeof(SqlService)); while (!result.CloseStatus.HasValue) { //string answer = @"The server received the following message: "; //byte[] answerBuffer = System.Text.Encoding.UTF8.GetBytes(answer); //await webSocket.SendAsync( // new ArraySegment<byte>(answerBuffer, 0, answerBuffer.Length) // , System.Net.WebSockets.WebSocketMessageType.Text // , false, System.Threading.CancellationToken.None //); //wtw.WriteLine("Test 123"); //wtw.Transmit(); //await System.Threading.Tasks.Task.Delay(30); await SqlServiceJsonHelper.AnyDataReaderToJson("SELECT * FROM T_Benutzer", null, service, wtw, RenderType_t.DataTable); await wtw.TransmitAsync(); //await System.Threading.Tasks.Task.Delay(3000); //wtw.WriteLine("Test 456"); //wtw.Transmit(); //await System.Threading.Tasks.Task.Delay(30); //using (Newtonsoft.Json.JsonTextWriter jsonWriter = // new Newtonsoft.Json.JsonTextWriter(wtw)) //{ //} result = await webSocket.ReceiveAsync( new System.ArraySegment <byte>(buffer) , System.Threading.CancellationToken.None ); } // Whend await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, System.Threading.CancellationToken.None); } // End Task GetTableAsync
private async Task ProcessSystemWebsocket( IWebSocketContext context, System.Net.WebSockets.WebSocket webSocket, CancellationToken ct) { // define a receive buffer var receiveBuffer = new byte[ReceiveBufferSize]; // define a dynamic buffer that holds multi-part receptions var receivedMessage = new List <byte>(receiveBuffer.Length * 2); // poll the WebSockets connections for reception while (webSocket.State == System.Net.WebSockets.WebSocketState.Open) { // retrieve the result (blocking) var receiveResult = new WebSocketReceiveResult(await webSocket .ReceiveAsync(new ArraySegment <byte>(receiveBuffer), ct).ConfigureAwait(false)); if (receiveResult.MessageType == (int)System.Net.WebSockets.WebSocketMessageType.Close) { // close the connection if requested by the client await webSocket .CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, ct) .ConfigureAwait(false); return; } var frameBytes = new byte[receiveResult.Count]; Array.Copy(receiveBuffer, frameBytes, frameBytes.Length); OnFrameReceived(context, frameBytes, receiveResult); // add the response to the multi-part response receivedMessage.AddRange(frameBytes); if (receivedMessage.Count > _maximumMessageSize && _maximumMessageSize > 0) { // close the connection if message exceeds max length await webSocket.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.MessageTooBig, $"Message too big. Maximum is {_maximumMessageSize} bytes.", ct).ConfigureAwait(false); // exit the loop; we're done return; } // if we're at the end of the message, process the message if (!receiveResult.EndOfMessage) { continue; } OnMessageReceived(context, receivedMessage.ToArray(), receiveResult); receivedMessage.Clear(); } }
} // End Task DeserializeJSON private static async System.Threading.Tasks.Task <T> DeserializeJSON <T>( System.Net.WebSockets.WebSocket webSocket) { Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); T result = await DeserializeJSON <T>(webSocket, serializer); serializer = null; return(result); } // End Task DeserializeJSON
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.1 private static async System.Threading.Tasks.Task Echo( Microsoft.AspNetCore.Http.HttpContext context , System.Net.WebSockets.WebSocket webSocket) { WebSocketTextWriter wtw = new WebSocketTextWriter(webSocket); byte[] buffer = new byte[1024 * 4]; System.Net.WebSockets.WebSocketReceiveResult result = await webSocket.ReceiveAsync( new System.ArraySegment <byte>(buffer) , System.Threading.CancellationToken.None ); while (!result.CloseStatus.HasValue) { //string answer = @"The server received the following message: "; //byte[] answerBuffer = System.Text.Encoding.UTF8.GetBytes(answer); //await webSocket.SendAsync( // new ArraySegment<byte>(answerBuffer, 0, answerBuffer.Length) // , System.Net.WebSockets.WebSocketMessageType.Text // , false, System.Threading.CancellationToken.None //); wtw.WriteLine("Test 123"); await wtw.TransmitAsync(); wtw.WriteLine("Test 456"); await wtw.TransmitAsync(); wtw.WriteLine("Echo: "); await wtw.FlushAsync(); wtw.Write(@"The server received the following message: "); await wtw.FlushAsync(); // wtw.Send(false, new byte[0]); await webSocket.SendAsync( new System.ArraySegment <byte>(buffer, 0, result.Count) , result.MessageType , result.EndOfMessage , System.Threading.CancellationToken.None ); result = await webSocket.ReceiveAsync( new System.ArraySegment <byte>(buffer) , System.Threading.CancellationToken.None ); } // Whend await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, System.Threading.CancellationToken.None); } // End Task Echo
public static void AddSocket(string name, string guid, System.Net.WebSockets.WebSocket socket) { if (socketModels.Count(s => s.Name == name) <= 0) { socketModels.Add(new SocketModel { Name = name, Guid = guid, Socket = socket }); } }
private void CollectSocket(System.Net.WebSockets.WebSocket socket) { ISocket isocket = new WebSocket(socket, RandomId.Generate()); while (!csockets.TryAdd(isocket.Id, isocket)) { isocket = new WebSocket(socket, RandomId.Generate()); } isocket.OnSocketDisconnected += RemoveSocket; SendServerToken(isocket); OnConnectionRequested?.Invoke(isocket); }
public IConnection Get(System.Net.WebSockets.WebSocket socket) { if (socket == null) { return(null); } lock (mutex) { var connection = new Connection(logger, socket, packetDataSerializer); connections.Add(connection); return(connection); } }
public Task ExecuteAsync(System.Net.WebSockets.WebSocket socket, Thing thing, JsonElement data, JsonSerializerOptions options, IServiceProvider provider, CancellationToken cancellationToken) { var observer = provider.GetRequiredService <ThingObserver>(); foreach (var(@event, collection) in thing.ThingContext.Events) { if (data.TryGetProperty(@event, out _)) { collection.Added += observer.OnEvenAdded; } } return(Task.CompletedTask); }
private async void _Accept(HttpListenerContext context) { System.Net.WebSockets.HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null); System.Net.WebSockets.WebSocket webSocket = webSocketContext.WebSocket; TimeCounter timeCounter = new TimeCounter(); while (webSocket.State != System.Net.WebSockets.WebSocketState.Open) { if (timeCounter.Ticks > 60) { return; } } _AcceptEvent(new Peer(webSocket)); }
private static async System.Threading.Tasks.Task <T> DeserializeJSON <T>( System.Net.WebSockets.WebSocket webSocket , Newtonsoft.Json.JsonSerializer serializer) { T searchArguments = default(T); using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { byte[] buffer = new byte[1024 * 4]; System.Net.WebSockets.WebSocketReceiveResult result = null; do { result = await webSocket.ReceiveAsync( new System.ArraySegment <byte>(buffer) , System.Threading.CancellationToken.None ); ms.Write(buffer, 0, result.Count); } while (!result.EndOfMessage); // string json = System.Text.Encoding.UTF8.GetString(ms.ToArray()); // searchArguments = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchArguments>(json); ms.Position = 0; using (System.IO.TextReader tr = new System.IO.StreamReader(ms, System.Text.Encoding.UTF8)) { using (Newtonsoft.Json.JsonReader jsonReader = new Newtonsoft.Json.JsonTextReader(tr)) { try { searchArguments = serializer.Deserialize <T>(jsonReader); } catch (System.Exception ex) { System.Console.WriteLine(ex.Message); } } // End Using jsonReader } // End Using tr } // End Using ms return(searchArguments); } // End Task DeserializeJSON
public Task OnNewConnection(System.Net.WebSockets.WebSocket webSocket, ConnectionInfo connectionInfo) { var connectionInfoStr = $"WebSocket:{connectionInfo.RemoteIpAddress}:{connectionInfo.RemotePort}"; var cts = new CancellationTokenSource(); lock (webSocketContextQueue) webSocketContextQueue.Enqueue( new WebSocketContext( connectionInfoStr, webSocket, cts)); waitForConnectionAutoResetEvent.Set(); return(Task.Delay(-1, cts.Token).ContinueWith(t => { if (LogUtils.LogConnection) { Console.WriteLine("[Connection]{0} disconnected.", connectionInfoStr); } })); }
public static async Task SendAsync(this System.Net.WebSockets.WebSocket webSocket, string msg) { try { await Task.Run(() => { var buffer = Encoding.UTF8.GetBytes(msg); var arrSegment = new ArraySegment <byte>(buffer, 0, buffer.Length); lock (lockObj) { webSocket.SendAsync(arrSegment, System.Net.WebSockets.WebSocketMessageType.Text, true, CancellationToken.None); } }); } catch (Exception exc) { Console.WriteLine("wx 执行的错误"); Console.WriteLine(exc.Message); } }
} // End Task Echo public static void UseEcho(this Microsoft.AspNetCore.Builder.IApplicationBuilder app) { app.Use(async(context, next) => { if (context.Request.Path == "/ws") { if (context.WebSockets.IsWebSocketRequest) { System.Net.WebSockets.WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); await Echo(context, webSocket); } else { context.Response.StatusCode = 400; } } else { await next(); } }); } // End Sub UseEcho
public IExtensionConnection Get( System.Net.WebSockets.WebSocket socket, IReadOnlyDictionary <string, string> requestHeaders) { var sessionId = requestHeaders.GetSessionId(); if (!sessionInfoProvider.TryGet(sessionId, out var session)) { return(null); } if (socket == null) { return(null); } lock (mutex) { var connection = new ExtensionWebSocketConnection(logger, socket, packetDataSerializer, session, requestHeaders["broadcasterId"]); connections[sessionId] = connection; return(connection); } }
} // End Sub UseRansackSearchAndReplace public static void UseRansackSearch( this Microsoft.AspNetCore.Builder.IApplicationBuilder app , string path) { app.Use(async(context, next) => { if (context.Request.Path.Equals(new Microsoft.AspNetCore.Http.PathString(path), System.StringComparison.InvariantCultureIgnoreCase)) { if (context.WebSockets.IsWebSocketRequest) { System.Net.WebSockets.WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); await Ransack(context, webSocket); } else { context.Response.StatusCode = 400; } } else { await next(); } }); } // End Sub UseRansackSearch
} // End Task GetTableAsync public static void UseTable(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, string path) { Microsoft.AspNetCore.Http.PathString ps = new Microsoft.AspNetCore.Http.PathString(path); app.Use(async(context, next) => { if (context.Request.Path == ps) { if (context.WebSockets.IsWebSocketRequest) { System.Net.WebSockets.WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); await GetTableAsync(context, webSocket); } else { context.Response.StatusCode = 400; } } else { await next(); } }); } // End Sub UseTable
public System.Threading.Tasks.Task ProcessSocketAsync(System.Net.WebSockets.WebSocket socket) { throw null; }
public websockerPeer(System.Net.WebSockets.WebSocket websocket) { this.websocket = websocket; }
public static IChannel Create(WebSocketConfig config, HttpContext context, System.Net.WebSockets.WebSocket socket, CancellationToken token) { return(WebSocketChannel.Create(context, socket, config, token)); }
public static async Task HandleWebSocketRequestAsync(HttpContext context) { void BadRequest(string message) { context.Response.StatusCode = StatusCodes.Status400BadRequest; context.Response.ContentType = "text/plain; charset=utf-8"; using (var sw = new System.IO.StreamWriter(context.Response.Body)) { sw.WriteLine(message); } } // // Make sure we get a good ID // if (!context.Request.Query.TryGetValue("id", out var idValues)) { BadRequest("Missing `id`"); return; } var id = idValues.LastOrDefault(); if (id == null || id.Length != 32) { BadRequest("Invalid `id`"); return; } // // Clear old sessions // var toClear = pendingSessions.Where(x => (DateTime.UtcNow - x.Value.CreateTimeUtc) > SessionTimeout).ToList(); foreach (var c in toClear) { pendingSessions.TryRemove(c.Key, out var _); } // // Find the pending session // if (!pendingSessions.TryRemove(id, out var activeSession)) { BadRequest("Unknown `id`"); return; } // // Set the element's dimensions // if (!context.Request.Query.TryGetValue("w", out var wValues) || wValues.Count < 1) { BadRequest("Missing `w`"); return; } if (!context.Request.Query.TryGetValue("h", out var hValues) || hValues.Count < 1) { BadRequest("Missing `h`"); return; } var icult = System.Globalization.CultureInfo.InvariantCulture; if (!double.TryParse(wValues.Last(), System.Globalization.NumberStyles.Any, icult, out var w)) { w = 640; } if (!double.TryParse(hValues.Last(), System.Globalization.NumberStyles.Any, icult, out var h)) { h = 480; } // // OK, Run // var token = CancellationToken.None; System.Net.WebSockets.WebSocket webSocket = null; void Error(string m, Exception e) => activeSession?.Logger?.LogWarning(e, m); // // Create a new session and let it handle everything from here // try { webSocket = await context.WebSockets.AcceptWebSocketAsync("Goui").ConfigureAwait(false); var session = new Goui.WebSocketSession(webSocket, activeSession.Element, activeSession.DisposeElementAfterSession, w, h, Error, token); await session.RunAsync().ConfigureAwait(false); } catch (System.Net.WebSockets.WebSocketException ex) when(ex.WebSocketErrorCode == System.Net.WebSockets.WebSocketError.ConnectionClosedPrematurely) { // The remote party closed the WebSocket connection without completing the close handshake. } catch (Exception ex) { context.Abort(); activeSession?.Logger?.LogWarning(ex, "Web socket session failed"); } finally { webSocket?.Dispose(); } }
public WebSocketSession(System.Net.WebSockets.WebSocket socket) { this.socket = socket; this.winid = -1; }
/// <summary> /// Initializes a new instance of the <see cref="EtpServerHandler"/> class. /// </summary> /// <param name="webSocket">The web socket.</param> /// <param name="application">The server application name.</param> /// <param name="version">The server application version.</param> /// <param name="headers">The WebSocket or HTTP headers.</param> public EtpServerHandler(System.Net.WebSockets.WebSocket webSocket, string application, string version, IDictionary <string, string> headers) : base(webSocket, application, version, headers) { }
/// <summary> /// Invoked when this handler is determined to be the best suited to handle the supplied connection. /// </summary> /// <param name="context"> /// The HTTP context. /// </param> /// <returns> /// The handling task. /// </returns> public override async Task Handle(HttpContext context) { ClientWebSocket wsServer = null; System.Net.WebSockets.WebSocket wsClient = null; try { // First we need the URL for this connection, since it's been requested to be // upgraded to a websocket. var connFeature = context.Features.Get <IHttpRequestFeature>(); string fullUrl = string.Empty; if (connFeature != null && connFeature.RawTarget != null && !string.IsNullOrEmpty(connFeature.RawTarget) && !(string.IsNullOrWhiteSpace(connFeature.RawTarget))) { fullUrl = $"{context.Request.Scheme}://{context.Request.Host}{connFeature.RawTarget}"; } else { fullUrl = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}"; } // Need to replate the scheme with appropriate websocket scheme. if (fullUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) { fullUrl = "ws://" + fullUrl.Substring(7); } else if (fullUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { fullUrl = "wss://" + fullUrl.Substring(8); } // Next we need to try and parse the URL as a URI, because the websocket client // requires this for connecting upstream. if (!Uri.TryCreate(fullUrl, UriKind.RelativeOrAbsolute, out Uri wsUri)) { LoggerProxy.Default.Error("Failed to parse websocket URI."); return; } // Create the websocket that's going to connect to the remote server. wsServer = new ClientWebSocket(); wsServer.Options.Cookies = new System.Net.CookieContainer(); //wsServer.Options.SetBuffer((int)ushort.MaxValue * 16, (int)ushort.MaxValue * 16); foreach (var proto in context.WebSockets.WebSocketRequestedProtocols) { wsServer.Options.AddSubProtocol(proto); } foreach (var hdr in context.Request.Headers) { if (!ForbiddenWsHeaders.IsForbidden(hdr.Key)) { try { wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString()); } catch (Exception hdrException) { LoggerProxy.Default.Error(hdrException); } } } foreach (var cookie in context.Request.Cookies) { try { wsServer.Options.Cookies.Add(new Uri(fullUrl, UriKind.Absolute), new System.Net.Cookie(cookie.Key, System.Net.WebUtility.UrlEncode(cookie.Value))); } catch (Exception e) { LoggerProxy.Default.Error("Error while attempting to add websocket cookie."); LoggerProxy.Default.Error(e); } } if (context.Connection.ClientCertificate != null) { wsServer.Options.ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection(new[] { context.Connection.ClientCertificate.ToV2Certificate() }); } // Connect the server websocket to the upstream, remote webserver. await wsServer.ConnectAsync(wsUri, context.RequestAborted); foreach (string key in wsServer.ResponseHeaders) { if (!ForbiddenWsHeaders.IsForbidden(key)) { try { var value = wsServer.ResponseHeaders[key]; context.Response.Headers[key] = wsServer.ResponseHeaders[key]; } catch (Exception hdrException) { LoggerProxy.Default.Error(hdrException); } } } // Create, via acceptor, the client websocket. This is the local machine's websocket. wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null); // Match the HTTP version of the client on the upstream request. We don't want to // transparently pass around headers that are wrong for the client's HTTP version. Version upstreamReqVersionMatch = null; Match match = s_httpVerRegex.Match(context.Request.Protocol); if (match != null && match.Success) { upstreamReqVersionMatch = Version.Parse(match.Value); } var msgNfo = new HttpMessageInfo { Url = wsUri, Method = new HttpMethod(context.Request.Method), IsEncrypted = context.Request.IsHttps, Headers = context.Request.Headers.ToNameValueCollection(), HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0), MessageProtocol = MessageProtocol.WebSocket, MessageType = MessageType.Request, RemoteAddress = context.Connection.RemoteIpAddress, RemotePort = (ushort)context.Connection.RemotePort, LocalAddress = context.Connection.LocalIpAddress, LocalPort = (ushort)context.Connection.LocalPort }; _configuration.NewHttpMessageHandler?.Invoke(msgNfo); switch (msgNfo.ProxyNextAction) { case ProxyNextAction.DropConnection: { await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); return; } } var serverMessageInfo = new HttpMessageInfo { Url = wsUri, MessageId = msgNfo.MessageId, Method = new HttpMethod(context.Request.Method), IsEncrypted = context.Request.IsHttps, Headers = context.Request.Headers.ToNameValueCollection(), HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0), MessageProtocol = MessageProtocol.WebSocket, MessageType = MessageType.Response, RemoteAddress = context.Connection.RemoteIpAddress, RemotePort = (ushort)context.Connection.RemotePort, LocalAddress = context.Connection.LocalIpAddress, LocalPort = (ushort)context.Connection.LocalPort }; var clientMessageInfo = new HttpMessageInfo { Url = wsUri, MessageId = msgNfo.MessageId, IsEncrypted = context.Request.IsHttps, Headers = context.Request.Headers.ToNameValueCollection(), HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0), MessageProtocol = MessageProtocol.WebSocket, MessageType = MessageType.Request, RemoteAddress = context.Connection.RemoteIpAddress, RemotePort = (ushort)context.Connection.RemotePort, LocalAddress = context.Connection.LocalIpAddress, LocalPort = (ushort)context.Connection.LocalPort }; bool inspect = true; switch (msgNfo.ProxyNextAction) { case ProxyNextAction.AllowAndIgnoreContent: case ProxyNextAction.AllowAndIgnoreContentAndResponse: { inspect = false; } break; } // Spawn an async task that will poll the remote server for data in a loop, and then // write any data it gets to the client websocket. var serverTask = Task.Run(async() => { System.Net.WebSockets.WebSocketReceiveResult serverResult = null; var serverBuffer = new byte[1024 * 4]; try { bool looping = true; serverResult = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); while (looping && !serverResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested) { if (inspect) { serverMessageInfo.Body = new Memory <byte>(serverBuffer, 0, serverResult.Count); switch (serverResult.MessageType) { case System.Net.WebSockets.WebSocketMessageType.Binary: { serverMessageInfo.BodyContentType = s_octetStreamContentType; } break; case System.Net.WebSockets.WebSocketMessageType.Text: { serverMessageInfo.BodyContentType = s_plainTextContentType; } break; } _configuration.HttpMessageWholeBodyInspectionHandler?.Invoke(serverMessageInfo); } switch (serverMessageInfo.ProxyNextAction) { case ProxyNextAction.DropConnection: { looping = false; } break; default: { await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverResult.Count), serverResult.MessageType, serverResult.EndOfMessage, context.RequestAborted); if (!wsClient.CloseStatus.HasValue) { serverResult = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); continue; } } break; } looping = false; } await wsClient.CloseAsync(serverResult.CloseStatus.Value, serverResult.CloseStatusDescription, context.RequestAborted); } catch (Exception err) { LoggerProxy.Default.Error(err); try { var closeStatus = serverResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure; var closeMessage = serverResult?.CloseStatusDescription ?? string.Empty; await wsClient.CloseAsync(closeStatus, closeMessage, context.RequestAborted); } catch { } } }); // Spawn an async task that will poll the local client websocket, in a loop, and then // write any data it gets to the remote server websocket. var clientTask = Task.Run(async() => { System.Net.WebSockets.WebSocketReceiveResult clientResult = null; var clientBuffer = new byte[1024 * 4]; try { bool looping = true; clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted); while (looping && !clientResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested) { if (inspect) { clientMessageInfo.Body = new Memory <byte>(clientBuffer, 0, clientResult.Count); switch (clientResult.MessageType) { case System.Net.WebSockets.WebSocketMessageType.Binary: { clientMessageInfo.BodyContentType = s_octetStreamContentType; } break; case System.Net.WebSockets.WebSocketMessageType.Text: { clientMessageInfo.BodyContentType = s_plainTextContentType; } break; } _configuration.HttpMessageWholeBodyInspectionHandler?.Invoke(clientMessageInfo); } switch (clientMessageInfo.ProxyNextAction) { case ProxyNextAction.DropConnection: { looping = false; } break; default: { await wsServer.SendAsync(new ArraySegment <byte>(clientBuffer, 0, clientResult.Count), clientResult.MessageType, clientResult.EndOfMessage, context.RequestAborted); if (!wsServer.CloseStatus.HasValue) { clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted); continue; } } break; } looping = false; } await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted); } catch (Exception err) { LoggerProxy.Default.Error(err); try { var closeStatus = clientResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure; var closeMessage = clientResult?.CloseStatusDescription ?? string.Empty; await wsServer.CloseAsync(closeStatus, closeMessage, context.RequestAborted); } catch { } } }); // Above, we have created a bridge between the local and remote websocket. Wait for // both associated tasks to complete. await Task.WhenAll(serverTask, clientTask); } catch (Exception wshe) { LoggerProxy.Default.Error(wshe); } finally { if (wsClient != null) { wsClient.Dispose(); wsClient = null; } if (wsServer != null) { wsServer.Dispose(); wsServer = null; } } }