// 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
// 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
/// <summary> /// On receiving data handler. /// </summary> /// <param name="data">The data received.</param> /// <param name="result">The received result.</param> private void ReceiveHandler(byte[] data, System.Net.WebSockets.WebSocketReceiveResult result) { // If data exists. if (data != null && data.Length > 0) { // Write the buffer. _writeStream.Write(data, 0, result.Count); } // Is the end of the data. if (result.EndOfMessage) { // Got translation. OnTranslationReceived?.Invoke(this, new EventArgs()); } }
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
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMvc(); app.UseWebSockets(); app.Use(async(http, next) => { if (http.WebSockets.IsWebSocketRequest && http.Request.Path == "/ws") { Program.wb = await http.WebSockets.AcceptWebSocketAsync(); await Task.Run(async() => { while (Program.wb.State == System.Net.WebSockets.WebSocketState.Open) { byte[] bt = new byte[1024]; System.Net.WebSockets.WebSocketReceiveResult rc = await Program.wb.ReceiveAsync(bt, CancellationToken.None); await Program.wb.SendAsync(bt, System.Net.WebSockets.WebSocketMessageType.Text, true, CancellationToken.None); } }); } else { await next(); } }); }
private static async System.Threading.Tasks.Task Prototype201802084_1() { // todo We need exception handling here. { double dateTimeFrequencyToPhaseFrequencyRatio = (double)System.TimeSpan.TicksPerSecond / (double)System.Diagnostics.Stopwatch.Frequency; long basePhase = System.Diagnostics.Stopwatch.GetTimestamp(); long baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks; basePhase = System.Diagnostics.Stopwatch.GetTimestamp(); baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks; var clientWebSocket = new System.Net.WebSockets.ClientWebSocket(); //System.Threading.Tasks.Task task = await clientWebSocket.ConnectAsync (new System.Uri //(@"wss://ws-feed-public.sandbox.gdax.com"), (@"wss://ws-feed.gdax.com"), System.Threading.CancellationToken.None ); // todo ??? The caller really should do this if needed. // todo ??? But any method really should do this // todo ??? if after {await} it's not supposed to return to the synchronization context. //// todo Comment in other places where we don't call this. //.ConfigureAwait(false); //int timeSpanInMilliSeconds = System.Environment.TickCount; // todo Remember to call this even if the task already completed -- to rethrow any exceptions. // todo {task.Result} also waits, right? //task.Wait(); //task.RunSynchronously(); //timeSpanInMilliSeconds = System.Environment.TickCount - timeSpanInMilliSeconds; //>>>clientWebSocket.ReceiveAsync if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open) { // todo Prototype subscribe/unsubscribe for 1 instrument at a time. const string channelName = //@"heartbeat"; //@"ticker"; @"level2"; //@"user"; //@"matches"; //@"full"; const string requestString = //Newtonsoft.Json.JsonConvert.SerializeObject // ( new // { // type = "subscribe", // product_ids = new string[] { @"ETH-USD", @"ETH-EUR", }, // } // ); "{" + "\"type\":\"subscribe\"," + "\"channels\":[{\"name\":\"" + channelName + "\",\"product_ids\":[\"BTC-USD\",\"BTC-EUR\"]}]" + "}"; byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString); await clientWebSocket.SendAsync (new System.ArraySegment <byte>(requestBytes), // todo ??? Binary didn't work, right? System.Net.WebSockets.WebSocketMessageType.Text, //System.Net.WebSockets.WebSocketMessageType.Binary, true, System.Threading.CancellationToken.None ); // todo This really doesn't need to be more than 16K, right? var receiveBuffer = new System.ArraySegment <byte>(new byte[33 * 1024]); for (bool isMessageBegin = true; ;) { if (clientWebSocket.State != System.Net.WebSockets.WebSocketState.Open) { System.Console.WriteLine(@"201802085"); break; } else { } System.Net.WebSockets.WebSocketReceiveResult webSocketReceiveResult = await clientWebSocket.ReceiveAsync(receiveBuffer, System.Threading.CancellationToken.None); // todo ??? if (webSocketReceiveResult.Count <= 0) { System.Console.WriteLine(@"201802086"); break; } else { } if (isMessageBegin) { isMessageBegin = false; System.Console.WriteLine(','); //System.Console.WriteLine(); long currentUtcDateTimeInTicks = (long)((double)(ulong)(System.Diagnostics.Stopwatch.GetTimestamp() - basePhase) * dateTimeFrequencyToPhaseFrequencyRatio + 0.5) + baseUtcDateTimeInTicks; System.Console.Write ((new System.DateTime(currentUtcDateTimeInTicks)).ToString(@"o", System.Globalization.DateTimeFormatInfo.InvariantInfo)); } else { } string string1 = System.Text.Encoding.ASCII.GetString(receiveBuffer.Array, 0, webSocketReceiveResult.Count); System.Console.Write(string1); if (webSocketReceiveResult.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) { System.Console.WriteLine(@"201802087"); break; } else { } if (webSocketReceiveResult.EndOfMessage) { isMessageBegin = true; //break; } else { } } } else { System.Console.WriteLine(@"201802088"); } // todo ??? WebSocketState >= CloseSent clientWebSocket.Dispose(); } StaticBool1_ = true; }
public async void conectar(bool enBaseDatos = true) { try { await cliente.ConnectAsync(new Uri("ws://irc-ws.chat.twitch.tv"), cancellationToken); if (cliente.State == System.Net.WebSockets.WebSocketState.Open) { byte[] bufferByte = new byte[6000]; int estado = 0; string[] ESPERAS = { ":tmi.twitch.tv 376 " + canal + " :>", ":End of /NAMES list" }; System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"(.*)\!(.*)@(.*)\.tmi\.twitch\.tv (PRIVMSG|PART) #(.*) :(.*)", System.Text.RegularExpressions.RegexOptions.RightToLeft); ArraySegment <byte> buffer = new ArraySegment <byte>(bufferByte); await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("PASS oauth:" + oauth)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken); await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("NICK " + canal)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken); //cliente.Options. //a cliente.ReceiveAsync(buffer, cancellationToken); //envioDatos. System.Net.WebSockets.WebSocketReceiveResult resultado = await cliente.ReceiveAsync(buffer, cancellationToken); while (cliente.State == System.Net.WebSockets.WebSocketState.Open) { string[] respuestas = arrayString(bufferByte, resultado.Count).Replace("\n", "\r").Replace("\r\r", "\r").Split('\r'); for (int i = 0; i < respuestas.Length; i++) { string respuesta = respuestas[i]; if (respuesta == ESPERAS[0]) { estado++; } string mensaje = ""; if (respuesta.Length > 0) { switch (estado) { case 1: estado++; mensaje = "JOIN #" + canal; await cliente.SendAsync(new ArraySegment <byte>(arrayBytes(mensaje)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken); break; } if (respuesta == "PING :tmi.twitch.tv") { await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("PONG :tmi.twitch.tv")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken); } else { if (estado > 0) { //System.Diagnostics.Trace.WriteLine(respuesta); //System.Diagnostics.Trace.WriteLine(toxicidad(respuesta)); while (mensajesEnviar.Count > 0) { string mensajeTexto = "PRIVMSG #" + Configuracion.parametro("canal") + " :" + mensajesEnviar[0]; await cliente.SendAsync(new ArraySegment <byte>(arrayBytes(mensajeTexto)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken); mensajesEnviar.RemoveAt(0); } System.Text.RegularExpressions.Match coincidencias = regEx.Match(respuesta); if (coincidencias.Success) { string[] partes = regEx.GetGroupNames(); //System.Text.RegularExpressions.Group grp /*foreach (string nombre in partes) { * System.Text.RegularExpressions.Group grp = coincidencias.Groups[nombre]; * //Console.WriteLine(" {0}: '{1}'", name, grp.Value); * }*/ System.Diagnostics.Trace.WriteLine((coincidencias.Groups["0"].Value)); System.Diagnostics.Trace.WriteLine("" + (coincidencias.Groups["2"].Value) + " = " + (coincidencias.Groups["6"].Value)); string aliasUsuario = coincidencias.Groups["2"].Value.ToLower(); long idUsuario = -1; try { Datos usuarios = BD.consulta("select id,avatar from usuarios where alias='" + aliasUsuario + "'"); if (usuarios.Length == 0) { String avatar = null; JSON usuario = infoUsuario(aliasUsuario); try { avatar = usuario["data"][0]["profile_image_url"].ToString(); } catch { } int numeroAfectados = BD.ejecutar("insert into usuarios (alias, avatar, nombre, userID) values ('" + aliasUsuario + "'," + (avatar != null ? "'" + avatar + "'" : "null") + ",'" + usuario["data"][0]["display_name"].ToString() + "','" + usuario["data"][0]["id"].ToString() + "')"); if (numeroAfectados == 1) { idUsuario = BD.id; } } else { if (usuarios[0]["avatar"] == null || usuarios[0]["avatar"].ToString().Length == 0) { JSON usuario = infoUsuario(aliasUsuario); string avatar = usuario["data"][0]["profile_image_url"].ToString(); BD.ejecutar("update usuarios set avatar='" + avatar + "' where alias='" + aliasUsuario + "'"); } idUsuario = long.Parse(usuarios[0]["id"].ToString()); } string texto = coincidencias.Groups["6"].Value; double puntuacion = toxicidad(texto); texto = tratarMensaje(texto, puntuacion); if (enBaseDatos) { try { texto = texto.Replace("\"", "\\\"").Replace("'", "''"); BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1," + idUsuario + ", '" + texto + "'," + puntuacion.ToString().Replace(",", ".") + ")"); }catch (Exception ex1) { BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1," + idUsuario + ", '" + aUTF8(texto) + "'," + puntuacion.ToString().Replace(",", ".") + ")"); } } } catch (Exception ex) { LOG.debug(ex.Message, "Conectar a twitch"); } } } } } } resultado = await cliente.ReceiveAsync(buffer, cancellationToken); } //resultado. //System.Diagnostics.Trace.WriteLine(arrayString(bufferByte)); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); } }
public async void conectarTopicos(bool enBaseDatos = true) { try { await clienteTopic.ConnectAsync(new Uri("wss://pubsub-edge.twitch.tv"), cancellationToken2); if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open) { byte[] bufferByte = new byte[6000]; int estado = 0; string[] ESPERAS = { "{ \"type\": \"PONG\" }", ":End of /NAMES list" }; System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"(.*)\!(.*)@(.*)\.tmi\.twitch\.tv (PRIVMSG|PART) #(.*) :(.*)", System.Text.RegularExpressions.RegexOptions.RightToLeft); ArraySegment <byte> buffer = new ArraySegment <byte>(bufferByte); System.Windows.Forms.Timer ping = new System.Windows.Forms.Timer(); ping.Interval = 15000; ping.Enabled = true; ping.Tick += async(object sender, EventArgs e) => { if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open) { await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"PING\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2); } else { //await clienteTopic.CloseAsync(); await clienteTopic.ConnectAsync(new Uri("wss://pubsub-edge.twitch.tv"), cancellationToken2); if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open) { await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"RECONNECT\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2); } } }; /*await cliente.SendAsync(new ArraySegment<byte>(arrayBytes("NICK " + canal)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);*/ await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"PING\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2); System.Net.WebSockets.WebSocketReceiveResult resultado = await clienteTopic.ReceiveAsync(buffer, cancellationToken2); while (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open) { string[] respuestas = arrayString(bufferByte, resultado.Count).Replace("\n", "\r").Replace("\r\r", "\r").Split('\r'); for (int i = 0; i < respuestas.Length; i++) { string respuesta = respuestas[i]; string mensaje = ""; if (respuesta.Length > 0) { switch (estado) { case 0: estado++; mensaje = "{\"type\":\"LISTEN\",\"nonce\":\"\",\"data\":{\"topics\": [\"channel-bits-events-v2." + Configuracion.parametro("id_usuario") + "\",\"whispers." + Configuracion.parametro("id_usuario") + "\",\"channel-subscribe-events-v1." + Configuracion.parametro("id_usuario") + "\"],\"auth_token\": \"" + Configuracion.parametro("oauth") + "\"}}"; await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes(mensaje)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2); break; case 1: if (respuesta != ESPERAS[0]) { JSON respuestaJSON = new JSON(); respuestaJSON.parse(respuesta); switch (respuestaJSON["type"].ToString()) { case "MESSAGE": if (respuestaJSON["data"]["topic"].ToString() == "whispers." + Configuracion.parametro("id_usuario")) { string texto = ((Entidad)respuestaJSON["data"]["message"])["body"].ToString(); double puntuacion = toxicidad(texto); tratarMensaje(texto, puntuacion); if (enBaseDatos) { BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1,1, '" + texto.Replace("\"", "\\\"") + "'," + puntuacion.ToString().Replace(",", ".") + ")"); } } break; } System.IO.File.AppendAllText("sucripcion.txt", respuesta + "\r\n"); } break; } } } try { resultado = await clienteTopic.ReceiveAsync(buffer, cancellationToken); } catch (Exception ex1) { System.Diagnostics.Trace.WriteLine(ex1.Message); } } //resultado. //System.Diagnostics.Trace.WriteLine(arrayString(bufferByte)); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); } }
/// <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; } } }
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 fullUrl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request); // Need to replate the scheme with appropriate websocket scheme. if (fullUrl.StartsWith("http://")) { fullUrl = "ws://" + fullUrl.Substring(7); } else if (fullUrl.StartsWith("https://")) { 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 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() }); } var reqHeaderBuilder = new StringBuilder(); foreach (var hdr in context.Request.Headers) { if (!ForbiddenWsHeaders.IsForbidden(hdr.Key)) { reqHeaderBuilder.AppendFormat("{0}: {1}\r\n", hdr.Key, hdr.Value.ToString()); try { wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString()); Console.WriteLine("Set Header: {0} ::: {1}", hdr.Key, hdr.Value.ToString()); } catch (Exception hdrException) { Console.WriteLine("Failed Header: {0} ::: {1}", hdr.Key, hdr.Value.ToString()); LoggerProxy.Default.Error(hdrException); } } } reqHeaderBuilder.Append("\r\n"); LoggerProxy.Default.Info(string.Format("Connecting websocket to {0}", wsUri.AbsoluteUri)); // Connect the server websocket to the upstream, remote webserver. await wsServer.ConnectAsync(wsUri, context.RequestAborted); LoggerProxy.Default.Info(String.Format("Connected websocket to {0}", wsUri.AbsoluteUri)); // Create, via acceptor, the client websocket. This is the local machine's websocket. wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null); ProxyNextAction nxtAction = ProxyNextAction.AllowAndIgnoreContentAndResponse; string customResponseContentType = string.Empty; byte[] customResponse = null; m_msgBeginCb?.Invoke(wsUri, reqHeaderBuilder.ToString(), null, context.Request.IsHttps ? MessageType.SecureWebSocket : MessageType.WebSocket, MessageDirection.Request, out nxtAction, out customResponseContentType, out customResponse); switch (nxtAction) { case ProxyNextAction.DropConnection: { if (customResponse != null) { } await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); return; } } // 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 serverStatus = null; var serverBuffer = new byte[1024 * 4]; try { bool looping = true; serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); while (looping && !serverStatus.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested) { await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverStatus.Count), serverStatus.MessageType, serverStatus.EndOfMessage, context.RequestAborted); if (!wsClient.CloseStatus.HasValue) { serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); continue; } looping = false; } await wsClient.CloseAsync(serverStatus.CloseStatus.Value, serverStatus.CloseStatusDescription, context.RequestAborted); } catch { try { var closeStatus = serverStatus?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure; var closeMessage = serverStatus?.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) { 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; } looping = false; } await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted); } catch { 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) { if (wshe is System.Net.WebSockets.WebSocketException) { var cast = wshe as System.Net.WebSockets.WebSocketException; Console.WriteLine(cast.WebSocketErrorCode); if (cast.Data != null) { foreach (KeyValuePair <object, object> kvp in cast.Data) { Console.WriteLine("{0} ::: {1}", kvp.Key, kvp.Value); } } } LoggerProxy.Default.Error(wshe); } finally { if (wsClient != null) { wsClient.Dispose(); wsClient = null; } if (wsServer != null) { wsServer.Dispose(); wsServer = null; } } }
/// <summary> /// Initializes a new instance of the <see cref="WebSocketReceiveResult"/> class. /// </summary> /// <param name="results">The results.</param> public WebSocketReceiveResult(System.Net.WebSockets.WebSocketReceiveResult results) { _results = results; }
private static async System.Threading.Tasks.Task Prototype201803072_1() { // todo We need exception handling here. { double dateTimeFrequencyToPhaseFrequencyRatio = (double)System.TimeSpan.TicksPerSecond / (double)System.Diagnostics.Stopwatch.Frequency; long basePhase = System.Diagnostics.Stopwatch.GetTimestamp(); long baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks; basePhase = System.Diagnostics.Stopwatch.GetTimestamp(); baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks; var clientWebSocket = new System.Net.WebSockets.ClientWebSocket(); await clientWebSocket.ConnectAsync (new System.Uri (@"wss://testnet.bitmex.com/realtime"), //(@"wss://bitmex.com/realtime"), System.Threading.CancellationToken.None ); // todo ??? The caller really should do this if needed. // todo ??? But any method really should do this // todo ??? if after {await} it's not supposed to return to the synchronization context. //// todo Comment in other places where we don't call this. //.ConfigureAwait(false); if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open) { { const string message = @"GET/realtime"; string nonceAsString = (++Nonce_).ToString(); // todo Use ASCII encoding everywhere. byte[] signatureBytes = hmacsha256 (System.Text.Encoding.UTF8.GetBytes(ApiKeySecret_), System.Text.Encoding.UTF8.GetBytes(message + nonceAsString) ); string signatureString = ByteArrayToString(signatureBytes); /*const*/ string requestString = "{" + "\"op\":\"authKey\"," + "\"args\":[\"" + ApiKeyId_ + "\"," + nonceAsString + ",\"" + signatureString + "\"]" + "}"; byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString); await clientWebSocket.SendAsync (new System.ArraySegment <byte>(requestBytes), System.Net.WebSockets.WebSocketMessageType.Text, true, System.Threading.CancellationToken.None ); } if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open) { { const string subscriptionTopicName = //@"quote:XBTUSD"; //@"trade:XBTUSD"; //@"orderBookL2:XBTUSD"; //@"instrument:XBTUSD"; //@"instrument"; //@"liquidation"; //@"quoteBin1m:XBTUSD"; @"order"; const string requestString = "{" + "\"op\":\"subscribe\"," + "\"args\":[\"" + subscriptionTopicName + "\"]" + "}"; byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString); await clientWebSocket.SendAsync (new System.ArraySegment <byte>(requestBytes), // todo ??? For GDAX binary didn't work, right? System.Net.WebSockets.WebSocketMessageType.Text, //System.Net.WebSockets.WebSocketMessageType.Binary, true, System.Threading.CancellationToken.None ); } // todo For GDAX this really doesn't need to be more than 16K, right? var receiveBuffer = new System.ArraySegment <byte>(new byte[33 * 1024]); for (bool isMessageBegin = true; ;) { if (clientWebSocket.State != System.Net.WebSockets.WebSocketState.Open) { System.Console.WriteLine(@"201802085"); break; } else { } System.Net.WebSockets.WebSocketReceiveResult webSocketReceiveResult = await clientWebSocket.ReceiveAsync(receiveBuffer, System.Threading.CancellationToken.None); // todo Is this correct? // todo Are these conditions equivalent? if (webSocketReceiveResult.CloseStatus.HasValue || webSocketReceiveResult.Count <= 0) { System.Console.WriteLine(@"201802086"); break; } else { } if (isMessageBegin) { isMessageBegin = false; System.Console.WriteLine(','); //System.Console.WriteLine(); long currentUtcDateTimeInTicks = (long)((double)(ulong)(System.Diagnostics.Stopwatch.GetTimestamp() - basePhase) * dateTimeFrequencyToPhaseFrequencyRatio + 0.5) + baseUtcDateTimeInTicks; System.Console.Write ((new System.DateTime(currentUtcDateTimeInTicks)).ToString(@"o", System.Globalization.DateTimeFormatInfo.InvariantInfo)); } else { } // todo Preserve decoding state between decoding chunks. string string1 = System.Text.Encoding.ASCII.GetString(receiveBuffer.Array, 0, webSocketReceiveResult.Count); System.Console.Write(string1); if (webSocketReceiveResult.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) { System.Console.WriteLine(@"201802087"); break; } else { } if (webSocketReceiveResult.EndOfMessage) { isMessageBegin = true; //break; } else { } } } else { System.Console.WriteLine(@"201802088"); } } else { System.Console.WriteLine(@"201804021"); } // todo ??? WebSocketState >= CloseSent clientWebSocket.Dispose(); } StaticBool1_ = true; }
public MessageEventArgs(byte[] raw, System.Net.WebSockets.WebSocketReceiveResult result) { Result = result; Data = raw; }
/// <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; DiagnosticsWebSession diagSession = new DiagnosticsWebSession(); try { // First we need the URL for this connection, since it's been requested to be upgraded to // a websocket. var fullUrl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request); // 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); } diagSession.ClientRequestUri = fullUrl; // 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 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() }); } if (Collector.IsDiagnosticsEnabled) { var diagHeaderBuilder = new StringBuilder(); foreach (var hdr in context.Request.Headers) { diagHeaderBuilder.AppendFormat($"{hdr.Key}: {hdr.Value.ToString()}\r\n"); } diagSession.ClientRequestHeaders = diagHeaderBuilder.ToString(); } var reqHeaderBuilder = new StringBuilder(); foreach (var hdr in context.Request.Headers) { if (!ForbiddenWsHeaders.IsForbidden(hdr.Key)) { reqHeaderBuilder.AppendFormat("{0}: {1}\r\n", hdr.Key, hdr.Value.ToString()); try { wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString()); } catch (Exception hdrException) { LoggerProxy.Default.Error(hdrException); } } } reqHeaderBuilder.Append("\r\n"); diagSession.ServerRequestHeaders = reqHeaderBuilder.ToString(); // Connect the server websocket to the upstream, remote webserver. await wsServer.ConnectAsync(wsUri, context.RequestAborted); // Create, via acceptor, the client websocket. This is the local machine's websocket. wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null); var msgNfo = new HttpMessageInfo { Url = wsUri, IsEncrypted = context.Request.IsHttps, Headers = context.Request.Headers.ToNameValueCollection(), MessageProtocol = MessageProtocol.WebSocket, MessageType = MessageType.Request, RemoteAddress = context.Connection.RemoteIpAddress, RemotePort = (ushort)context.Connection.RemotePort, LocalAddress = context.Connection.LocalIpAddress, LocalPort = (ushort)context.Connection.LocalPort }; _newMessageCb?.Invoke(msgNfo); switch (msgNfo.ProxyNextAction) { case ProxyNextAction.DropConnection: { await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); return; } } // 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 serverStatus = null; var serverBuffer = new byte[1024 * 4]; try { bool looping = true; serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); while (looping && !serverStatus.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested) { await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverStatus.Count), serverStatus.MessageType, serverStatus.EndOfMessage, context.RequestAborted); if (!wsClient.CloseStatus.HasValue) { serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted); continue; } looping = false; } await wsClient.CloseAsync(serverStatus.CloseStatus.Value, serverStatus.CloseStatusDescription, context.RequestAborted); } catch { try { var closeStatus = serverStatus?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure; var closeMessage = serverStatus?.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) { 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; } looping = false; } await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted); } catch { 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 { Collector.ReportSession(diagSession); if (wsClient != null) { wsClient.Dispose(); wsClient = null; } if (wsServer != null) { wsServer.Dispose(); wsServer = null; } } }