コード例 #1
0
        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!"));
        }
コード例 #2
0
        public WebSocket(System.Net.WebSockets.WebSocket socket, int bufferSize = 8192)
        {
            this.Base       = socket;
            this.bufferSize = bufferSize;

            new Thread(Receive).Start();
        }
コード例 #3
0
ファイル: WebSocketServiceHost.cs プロジェクト: zt102545/Demo
        //创建链接
        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;
            }
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
        /// <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();
            }
        }
コード例 #6
0
ファイル: WS_Buffer.cs プロジェクト: kn201905/mdwiki_re
// ------------------------------------------------------------------------------------
        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));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        // 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
コード例 #9
0
ファイル: WebSocketsServer.cs プロジェクト: wcy-fmt/embedio
        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();
            }
        }
コード例 #10
0
        } // 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
コード例 #11
0
        // 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
コード例 #12
0
 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
         });
     }
 }
コード例 #13
0
        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);
        }
コード例 #14
0
 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);
     }
 }
コード例 #15
0
        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);
        }
コード例 #16
0
        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));
        }
コード例 #17
0
        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
コード例 #18
0
        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);
                }
            }));
        }
コード例 #19
0
 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);
     }
 }
コード例 #20
0
        } // 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
コード例 #21
0
        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);
            }
        }
コード例 #22
0
        } // 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
コード例 #23
0
        } // 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;
 }
コード例 #25
0
ファイル: Program.cs プロジェクト: molika202/lightchain
 public websockerPeer(System.Net.WebSockets.WebSocket websocket)
 {
     this.websocket = websocket;
 }
コード例 #26
0
 public static IChannel Create(WebSocketConfig config, HttpContext context,
                               System.Net.WebSockets.WebSocket socket, CancellationToken token)
 {
     return(WebSocketChannel.Create(context, socket, config, token));
 }
コード例 #27
0
ファイル: WebSocketHandler.cs プロジェクト: KevinGliewe/Goui
        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();
            }
        }
コード例 #28
0
 public WebSocketSession(System.Net.WebSockets.WebSocket socket)
 {
     this.socket = socket;
     this.winid  = -1;
 }
コード例 #29
0
 /// <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)
 {
 }
コード例 #30
0
        /// <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;
                }
            }
        }