using System; using System.Net; using System.Net.Sockets; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using System.Web; namespace AspNetTools { public static class WebSocketForwardModule { public static void ForwardCurrentContext(string opKey, string opValue, IPEndPoint endPoint, int bufferSize = 1024) { var ctx = HttpContext.Current; var req = HttpContext.Current.Request; if (req.QueryString[opKey] == opValue) { ctx.Handler = null; var rsp = HttpContext.Current.Response; //if (ctx.IsDebuggingEnabled == false && req.IsSecureConnection == false) //{ // rsp.ContentType = "text/html"; // rsp.Write("Prod env is Secure Connection required"); // ctx.ApplicationInstance.CompleteRequest(); // return; //} if (ctx.IsWebSocketRequest) { ctx.AcceptWebSocketRequest(async (ws) => { var fcl = new TcpClient(); fcl.Connect(endPoint); var ns = fcl.GetStream(); var tIn = Task.Run(async () => { var buf = new byte[bufferSize]; var arrSeg = new ArraySegment(buf); while (ws.WebSocket.CloseStatus.HasValue == false) { var x = await ws.WebSocket.ReceiveAsync(arrSeg, CancellationToken.None); await ns.WriteAsync(buf, 0, x.Count); } }); var tOut = Task.Run(async () => { var buf = new byte[bufferSize]; while (ws.WebSocket.CloseStatus.HasValue == false) { var count = await ns.ReadAsync(buf, 0, buf.Length); var arrSeg = new ArraySegment(buf, 0, count); await ws.WebSocket.SendAsync(arrSeg, WebSocketMessageType.Binary, true, CancellationToken.None); } }); Task.WaitAll(tIn, tOut); fcl.Close(); }); } else { rsp.ContentType = "text/html"; rsp.Write("Welcome back. Master!"); } } } } }