public void ConstructorTest_Success(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription)
 {
     var wsrr = new WebSocketReceiveResult(count, messageType, endOfMessage, closeStatus, closeStatusDescription);
     Assert.Equal(wsrr.Count, count);
     Assert.Equal(wsrr.MessageType, messageType);
     Assert.Equal(wsrr.EndOfMessage, endOfMessage);
     Assert.Equal(wsrr.CloseStatus, closeStatus);
     Assert.Equal(wsrr.CloseStatusDescription, closeStatusDescription);
 }
        public void ConstructorTest_Success(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription)
        {
            WebSocketReceiveResult wsrr;

            if (closeStatus == null && closeStatusDescription == null)
            {
                wsrr = new WebSocketReceiveResult(count, messageType, endOfMessage);
                Assert.Equal(count, wsrr.Count);
                Assert.Equal(messageType, wsrr.MessageType);
                Assert.Equal(endOfMessage, wsrr.EndOfMessage);
                Assert.Equal(null, wsrr.CloseStatus);
                Assert.Equal(null, wsrr.CloseStatusDescription);
            }

            wsrr = new WebSocketReceiveResult(count, messageType, endOfMessage, closeStatus, closeStatusDescription);
            Assert.Equal(count, wsrr.Count);
            Assert.Equal(messageType, wsrr.MessageType);
            Assert.Equal(endOfMessage, wsrr.EndOfMessage);
            Assert.Equal(closeStatus, wsrr.CloseStatus);
            Assert.Equal(closeStatusDescription, wsrr.CloseStatusDescription);
        }
Пример #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="result"></param>
 /// <param name="buffer"></param>
 /// <returns></returns>
 public abstract Task ReceiveAsync(WebSocket socket, WebSocketReceiveResult result, byte[] buffer);
Пример #4
0
        //### Accepting WebSocket connections
        // Calling `AcceptWebSocketAsync` on the `HttpListenerContext` will accept the WebSocket connection, sending the required 101 response to the client
        // and return an instance of `WebSocketContext`. This class captures relevant information available at the time of the request and is a read-only
        // type - you cannot perform any actual IO operations such as sending or receiving using the `WebSocketContext`. These operations can be
        // performed by accessing the `System.Net.WebSocket` instance via the `WebSocketContext.WebSocket` property.
        private async void ProcessRequest(HttpListenerContext listenerContext)
        {
            WebSocketContext webSocketContext = null;

            try
            {
                // When calling `AcceptWebSocketAsync` the negotiated subprotocol must be specified. This sample assumes that no subprotocol
                // was requested.
                webSocketContext = await listenerContext.AcceptWebSocketAsync(subProtocol : null);

                Interlocked.Increment(ref count);
                Console.WriteLine("Processed: {0}", count);
            }
            catch (Exception e)
            {
                // The upgrade process failed somehow. For simplicity lets assume it was a failure on the part of the server and indicate this using 500.
                listenerContext.Response.StatusCode = 500;
                listenerContext.Response.Close();
                Console.WriteLine("Exception: {0}", e);
                return;
            }

            WebSocket webSocket = webSocketContext.WebSocket;

            try
            {
                //### Receiving
                // Define a receive buffer to hold data received on the WebSocket connection. The buffer will be reused as we only need to hold on to the data
                // long enough to send it back to the sender.
                byte[] receiveBuffer = new byte[_SIZE];
                byte[] sendBuf;

                // While the WebSocket connection remains open run a simple loop that receives data and sends it back.
                while (webSocket.State == WebSocketState.Open)
                {
                    // The first step is to begin a receive operation on the WebSocket. `ReceiveAsync` takes two parameters:
                    //
                    // * An `ArraySegment` to write the received data to.
                    // * A cancellation token. In this example we are not using any timeouts so we use `CancellationToken.None`.
                    //
                    // `ReceiveAsync` returns a `Task<WebSocketReceiveResult>`. The `WebSocketReceiveResult` provides information on the receive operation that was just
                    // completed, such as:
                    //
                    // * `WebSocketReceiveResult.MessageType` - What type of data was received and written to the provided buffer. Was it binary, utf8, or a close message?
                    // * `WebSocketReceiveResult.Count` - How many bytes were read?
                    // * `WebSocketReceiveResult.EndOfMessage` - Have we finished reading the data for this message or is there more coming?
                    WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer), CancellationToken.None);

                    // The WebSocket protocol defines a close handshake that allows a party to send a close frame when they wish to gracefully shut down the connection.
                    // The party on the other end can complete the close handshake by sending back a close frame.
                    //
                    // If we received a close frame then lets participate in the handshake by sending a close frame back. This is achieved by calling `CloseAsync`.
                    // `CloseAsync` will also terminate the underlying TCP connection once the close handshake is complete.
                    //
                    // The WebSocket protocol defines different status codes that can be sent as part of a close frame and also allows a close message to be sent.
                    // If we are just responding to the client's request to close we can just use `WebSocketCloseStatus.NormalClosure` and omit the close message.
                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
                    }
                    // This echo server can't handle text frames so if we receive any we close the connection with an appropriate status code and message.
                    else if (receiveResult.MessageType == WebSocketMessageType.Text)
                    {
                        ///////////////////////////////////await webSocket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Cannot accept text frame", CancellationToken.None);

                        string s = System.Text.Encoding.UTF8.GetString(receiveBuffer).Split('\0')[0].Trim();
                        receiveBuffer = new byte[_SIZE];
                        Console.WriteLine(s);
                        Console.WriteLine(string.Empty);
                        sendBuf = System.Text.Encoding.UTF8.GetBytes(s);
                        if (s.StartsWith("ws-logid-"))
                        {
                            _clients.TryAdd(s, webSocket);
                        }
                        //else
                        //{
                        //    foreach (var kv in _clients)
                        //    {
                        //        if (kv.Value.State == WebSocketState.Open)
                        //        {
                        //            try
                        //            {
                        //                await kv.Value.SendAsync(new ArraySegment<byte>(sendBuf, 0, sendBuf.Length), WebSocketMessageType.Text, receiveResult.EndOfMessage, CancellationToken.None);
                        //            }
                        //            catch { }
                        //        }
                        //    }
                        //}
                    }

                    //////////////////////////// Otherwise we must have received binary data. Send it back by calling `SendAsync`. Note the use of the `EndOfMessage` flag on the receive result. This
                    //////////////////////////// means that if this echo server is sent one continuous stream of binary data (with EndOfMessage always false) it will just stream back the same thing.
                    //////////////////////////// If binary messages are received then the same binary messages are sent back.
                    //////////////////////////else
                    //////////////////////////{
                    //////////////////////////    string text = System.Text.Encoding.UTF8.GetString(receiveBuffer).Trim();
                    //////////////////////////    Console.WriteLine(text);
                    //////////////////////////    Console.WriteLine(string.Empty);

                    //////////////////////////    await webSocket.SendAsync(new ArraySegment<byte>(receiveBuffer, 0, receiveResult.Count), WebSocketMessageType.Binary, receiveResult.EndOfMessage, CancellationToken.None);
                    //////////////////////////}

                    // The echo operation is complete. The loop will resume and `ReceiveAsync` is called again to wait for the next data frame.
                }
            }
            catch (Exception e)
            {
                // Just log any exceptions to the console. Pretty much any exception that occurs when calling `SendAsync`/`ReceiveAsync`/`CloseAsync` is unrecoverable in that it will abort the connection and leave the `WebSocket` instance in an unusable state.
                Console.WriteLine("Exception: {0}", e);
            }
            finally
            {
                // Clean up by disposing the WebSocket once it is closed/aborted.
                if (webSocket != null)
                {
                    webSocket.Dispose();
                }
            }
        }
        /// <summary>
        /// Receives and decompresses text message from the WebSocket connection asynchronously.
        /// </summary>
        /// <param name="webSocket">The WebSocket representing the connection.</param>
        /// <param name="webSocketReceiveResult">The result of performing a first ReceiveAsync operation for this text message.</param>
        /// <param name="receivePayloadBuffer">The application buffer which was the storage location for first ReceiveAsync operation and will be internally used for subsequent ones in context of this text message.</param>
        /// <returns>The task object representing the asynchronous operation. The Result property on the task object returns a String containing the received message.</returns>
        public virtual async Task <string> DecompressTextMessageAsync(WebSocket webSocket, WebSocketReceiveResult webSocketReceiveResult, byte[] receivePayloadBuffer)
        {
            byte[] messagePayload = await ReceiveMessagePayloadAsync(webSocket, webSocketReceiveResult, receivePayloadBuffer);

            return(Encoding.UTF8.GetString(messagePayload));
        }
        protected static async Task <byte[]> ReceiveMessagePayloadAsync(WebSocket webSocket, WebSocketReceiveResult webSocketReceiveResult, byte[] receivePayloadBuffer)
        {
            byte[] messagePayload = null;

            if (webSocketReceiveResult.EndOfMessage)
            {
                messagePayload = new byte[webSocketReceiveResult.Count];
                Array.Copy(receivePayloadBuffer, messagePayload, webSocketReceiveResult.Count);
            }
            else
            {
                using (MemoryStream messagePayloadStream = new MemoryStream())
                {
                    messagePayloadStream.Write(receivePayloadBuffer, 0, webSocketReceiveResult.Count);
                    while (!webSocketReceiveResult.EndOfMessage)
                    {
                        webSocketReceiveResult = await webSocket.ReceiveAsync(new ArraySegment <byte>(receivePayloadBuffer), CancellationToken.None);

                        messagePayloadStream.Write(receivePayloadBuffer, 0, webSocketReceiveResult.Count);
                    }

                    messagePayload = messagePayloadStream.ToArray();
                }
            }

            return(messagePayload);
        }
Пример #7
0
 private static bool IsMessageText(WebSocketReceiveResult result)
 => result.MessageType.Equals(WebSocketMessageType.Text);
        private async Task HandleWebSocket(WebSocketContext wsContext)
        {
            const int maxMessageSize = 102400;
            byte[] receiveBuffer = new byte[maxMessageSize];
            WebSocket subSocket = wsContext.WebSocket;
            WsConfSubscriber subscriber = new WsConfSubscriber(subSocket);
            await OnOpen(subscriber);
            while (true)
            {
                WebSocketReceiveResult receiveResult = null;
                try
                {
                    receiveResult = await subSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                }
                catch (WebSocketException wse)
                {
                    OnClose(subscriber, WebSocketCloseStatus.InvalidMessageType);

                    break;
                }

                if (receiveResult.MessageType == WebSocketMessageType.Close)
                {
                    OnClose(subscriber, receiveResult.CloseStatus.Value);
                    await subSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
                }
                else if (receiveResult.MessageType == WebSocketMessageType.Binary)
                {
                    OnClose(subscriber, WebSocketCloseStatus.InvalidMessageType);
                    await subSocket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Binary frame not allowed", CancellationToken.None);
                }
                else
                {
                    int count = receiveResult.Count;
                    while (receiveResult.EndOfMessage == false)
                    {
                        if (count >= maxMessageSize)
                        {
                            string closeMessage = string.Format("Max message size: {0} bytes.", maxMessageSize);
                            OnClose(subscriber, WebSocketCloseStatus.MessageTooBig);
                            await subSocket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None);
                            return;
                        }
                        receiveResult = await subSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer, count, maxMessageSize - count), CancellationToken.None);
                        if (receiveResult.Count == 0)
                        {

                        }
                        count += receiveResult.Count;
                    }
                    //var receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count);
                }
            }
            //WebSocket socket = context.WebSocket;
            //while (true)
            //{
            //    ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
            //    WebSocketReceiveResult result = await socket.ReceiveAsync(
            //        buffer, CancellationToken.None);
            //    if (socket.State == WebSocketState.Open)
            //    {
            //        string userMessage = Encoding.UTF8.GetString(
            //            buffer.Array, 0, result.Count);
            //        userMessage = "You sent: " + userMessage + " at " +
            //            DateTime.Now.ToLongTimeString();
            //        buffer = new ArraySegment<byte>(
            //            Encoding.UTF8.GetBytes(userMessage));
            //        await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
            //    }
            //    else
            //    {
            //        break;
            //    }
            //}
        }
Пример #9
0
        private async Task ProcessChat(AspNetWebSocketContext context)
        {
            WebSocket socket = context.WebSocket;
            string    user   = context.QueryString["brand"];

            try
            {
                if (!ConnectPool.ContainsKey(user))
                {
                    ConnectPool.Add(user, socket);
                }
                else
                {
                    WebSocket existSocket = ConnectPool[user];
                    if (existSocket != socket)
                    {
                        ConnectPool[user] = socket;
                    }
                }
                while (true)
                {
                    if (socket.State == WebSocketState.Open)
                    {
                        ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[2048]);
                        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                        try
                        {
                            #region 关闭Socket处理,删除连接池

                            if (socket.State != WebSocketState.Open)
                            {
                                if (ConnectPool.ContainsKey(user))
                                {
                                    ConnectPool.Remove(user);
                                }
                                break;
                            }

                            string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count); //发送过来的消息
                            SocketQueryParameter parameter = JsonConvert.DeserializeObject <SocketQueryParameter>(userMsg);
                            if (parameter != null)
                            {
                                buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(parameter.QueryParameter));

                                if (ConnectPool.ContainsKey(user))            //判断客户端是否在线
                                {
                                    WebSocket destSocket = ConnectPool[user]; //目的客户端
                                    if (destSocket != null && destSocket.State == WebSocketState.Open)
                                    {
                                        await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true,
                                                                   CancellationToken.None);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            await ConnectPool["ROS"].SendAsync(buffer, WebSocketMessageType.Text, true,
                                                               CancellationToken.None);
                            //消息转发异常处理,本次消息忽略 继续监听接下来的消息
                        }

                        #endregion
                    }
                    else
                    {
                        break;
                    }
                } //while end
            }
            catch (Exception ex)
            {
                //整体异常处理
                if (ConnectPool.ContainsKey(user))
                {
                    ConnectPool.Remove(user);
                }
            }
        }
Пример #10
0
        private async Task Receive(WebSocket socket, CancellationToken cancellationToken)
        {
            while (socket.State == WebSocketState.Open)
            {
                ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[1024 * 4]);
                WebSocketReceiveResult result = null;
                try
                {
                    using (var ms = new MemoryStream())
                    {
                        do
                        {
                            result = await socket.ReceiveAsync(buffer, cancellationToken);

                            ms.Write(buffer.Array, buffer.Offset, result.Count);
                        }while (!result.EndOfMessage);

                        ms.Seek(0, SeekOrigin.Begin);

                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            using (var reader = new StreamReader(ms, Encoding.UTF8))
                            {
                                string message = await reader.ReadToEndAsync();

                                await _webSocketHandler.ReceiveTextAsync(socket, result, message);
                            }
                        }
                        else if (result.MessageType == WebSocketMessageType.Binary)
                        {
                            using (BinaryReader binaryReader = new BinaryReader(ms, Encoding.UTF8))
                            {
                                var message = new BinaryMessage
                                {
                                    CommandType = (CommandType)binaryReader.ReadInt32(),
                                    DataType    = (MessageDataType)binaryReader.ReadByte(),
                                };
                                var dataLength = binaryReader.ReadInt32();
                                message.Data = binaryReader.ReadBytes(dataLength);
                                await _webSocketHandler.ReceiveBinaryAsync(socket, result, message);
                            }
                        }
                        else if (result.MessageType == WebSocketMessageType.Close)
                        {
                            try
                            {
                                await _webSocketHandler.OnDisconnected(new WebSocketClient()
                                {
                                    WebSocket = socket
                                });
                            }
                            catch (WebSocketException)
                            {
                                throw; //let's not swallow any exception for now
                            }
                        }
                    }
                }
                catch (UserFriendlyException e)
                {
                    var warn = new AlertMessageOutput
                    {
                        Title = "警告",
                        Type  = AlertType.Warning,
                        Text  = e.Message
                    };
                    await socket.SendMsgPackAsync(CommandType.AlertMessage, warn, cancellationToken);
                }
                catch (AggregateException)
                {
                    break;
                }
                catch (ThreadAbortException)
                {
                    break;
                }
                catch (TaskCanceledException)
                {
                    break;
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (WebSocketException e)
                {
                    if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
                    {
                        socket.Abort();
                    }
                }
                catch (AbpException e)
                {
                    break;
                }
            }
            await _webSocketHandler.OnDisconnected(new WebSocketClient()
            {
                WebSocket = socket
            });
        }
        public async Task ReceiveAsync(WebSocket socket, WebSocketReceiveResult result, Message receivedMessage)
        {
            // method invocation request.
            if (receivedMessage.MessageType == MessageType.MethodInvocation)
            {
                // retrieve the method invocation request.
                InvocationDescriptor invocationDescriptor = null;
                try
                {
                    invocationDescriptor = JsonConvert.DeserializeObject <InvocationDescriptor>(receivedMessage.Data, _jsonSerializerSettings);
                    if (invocationDescriptor == null)
                    {
                        return;
                    }
                }
                catch { return; } // ignore invalid data sent to the server.

                // if the unique identifier hasn't been set then the client doesn't want a return value.
                if (invocationDescriptor.Identifier == Guid.Empty)
                {
                    // invoke the method only.
                    try
                    {
                        await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor);
                    }
                    catch (Exception)
                    {
                        // we consume all exceptions.
                    }
                }
                else
                {
                    // invoke the method and get the result.
                    InvocationResult invokeResult;
                    try
                    {
                        // create an invocation result with the results.
                        invokeResult = new InvocationResult()
                        {
                            Identifier = invocationDescriptor.Identifier,
                            Result     = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor),
                            Exception  = null
                        };
                    }
                    // send the exception as the invocation result if there was one.
                    catch (Exception ex)
                    {
                        invokeResult = new InvocationResult()
                        {
                            Identifier = invocationDescriptor.Identifier,
                            Result     = null,
                            Exception  = new RemoteException(ex)
                        };
                    }

                    // send a message to the client containing the result.
                    var message = new Message()
                    {
                        MessageType = MessageType.MethodReturnValue,
                        Data        = JsonConvert.SerializeObject(invokeResult, _jsonSerializerSettings)
                    };
                    await SendMessageAsync(socket, message).ConfigureAwait(false);
                }
            }

            // method return value.
            else if (receivedMessage.MessageType == MessageType.MethodReturnValue)
            {
                var invocationResult = JsonConvert.DeserializeObject <InvocationResult>(receivedMessage.Data, _jsonSerializerSettings);
                // find the completion source in the waiting list.
                if (_waitingRemoteInvocations.ContainsKey(invocationResult.Identifier))
                {
                    // set the result of the completion source so the invoke method continues executing.
                    _waitingRemoteInvocations[invocationResult.Identifier].SetResult(invocationResult);
                    // remove the completion source from the waiting list.
                    _waitingRemoteInvocations.Remove(invocationResult.Identifier);
                }
            }
        }
Пример #12
0
        //Asynchronous request handler.
        public async Task WebSocketRequestHandler(WebSocketContext webSocketContext)
        {
            //Gets the current WebSocket object.
            WebSocket webSocket = webSocketContext.WebSocket;

            //check the integrity of the connection

            /*We define a certain constant which will represent
             * size of received data. It is established by us and
             * we can set any value. We know that in this case the size of the sent
             * data is very small.
             */
            const int maxMessageSize = 512;

            //Buffer for received bits.
            var receivedDataBuffer = new ArraySegment <Byte>(new Byte[maxMessageSize]);

            var cancellationToken = new CancellationToken();

            //Checks WebSocket state.
            while (webSocket.State == WebSocketState.Open)
            {
                //Reads data.
                WebSocketReceiveResult webSocketReceiveResult =
                    await webSocket.ReceiveAsync(receivedDataBuffer, cancellationToken);

                bool errorDetected = false;
                //If input frame is cancelation frame, send close command.
                if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure,
                                               String.Empty, cancellationToken);
                }
                else
                {
                    byte[] payloadData           = receivedDataBuffer.Array.ToList().GetRange(0, webSocketReceiveResult.Count).ToArray();
                    WebsocketDataPackage package = GetPackage(ref payloadData);

                    string clientWsToken = GetConnectionCredential(package.clientId).HashedKey;

                    if (!CheckDataIntegrity(package.Data, package.HashedKey, clientWsToken))
                    {
                        errorDetected = true;
                        byte[] serializedData    = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(package.Data) + clientWsToken);
                        string receivedHashedKey = Convert.ToBase64String(SHA1.Create().ComputeHash(serializedData));

                        string message =
                            String.Format("Corrupted package: SHA1 received: {0} SHA1 expected: {1}", receivedHashedKey, package.HashedKey);
                        Byte[] bytesToSend = System.Text.Encoding.UTF8.GetBytes(message);

                        //Sends data back.
                        await webSocket.SendAsync(new ArraySegment <byte>(bytesToSend),
                                                  WebSocketMessageType.Text, true, cancellationToken);
                    }

                    if (!errorDetected)
                    {
                        ConnectionCredentials cc = GetConnectionCredential(package.clientId);
                        if (!cc.ConnectionSet)
                        {
                            Connection conn = new Connection(cc, webSocket);
                            BindConnection(GetConnectionCredential(package.clientId), conn);
                        }
                        var newString =
                            String.Format("Hello, package with hashed key: " + package.HashedKey + " validated! Time {0}", DateTime.Now.ToString());
                        Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(newString);

                        //Sends data back.
                        await webSocket.SendAsync(new ArraySegment <byte>(bytes),
                                                  WebSocketMessageType.Text, true, cancellationToken);
                    }
                }
            }
        }
Пример #13
0
        public async Task WaitReceive()
        {
            // 1 - on attend la première data du client
            // qui doit etre son GUID

            var buffer = new byte[1024 * 4];
            WebSocketReceiveResult result = null;

            try
            {
                result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
            }
            catch (Exception err)
            {
                MustRemove = true;
                Console.WriteLine($"[VIEWER ERROR] {err.Message}");
                try
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Error waiting data", CancellationToken.None);
                }
                catch (Exception) { }
                return;
            }
            while (!result.CloseStatus.HasValue)
            {
                if (result.Count < 1)
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Missing data in answer", CancellationToken.None);

                    return;
                }

                string command = System.Text.Encoding.UTF8.GetString(buffer, 0, 1);
                Console.WriteLine($"[DISPLAY] Received command '{command}'");
                if (command == "Q")
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, $"[DISPLAY CLOSING] receive {command}", CancellationToken.None);

                    return;
                }
                if (command == "*")
                {
                    var b = new byte[1];
                    b[0] = (byte)'*';
                    await webSocket.SendAsync(new ArraySegment <byte>(b, 0, 1), WebSocketMessageType.Text, true, CancellationToken.None);

                    return;
                }
                if (command == "S")
                {
                    MainGame.RunSimulator();
                    return;
                }
                if (command != "M")
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[DISPLAY ERROR] Not the right answer, waiting M#, receive {command}", CancellationToken.None);

                    return;
                }

                /*if (result.Count < 1)
                 * {
                 *  MustRemove = true;
                 *  await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'D'", CancellationToken.None);
                 *  return;
                 * }*/
                //SendMapInfo();
                //SendBotInfo();

                try
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                }
                catch (Exception err)
                {
                    MustRemove = true;
                    System.Diagnostics.Debug.WriteLine($"[DISPLAY ERROR] {err.Message}");
                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Error waiting data", CancellationToken.None);
                    }
                    catch (Exception) { }
                    return;
                }
            }
            MustRemove = true;
            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
 public virtual void OnMessage(WebSocketReceiveResult result, ArraySegment <byte> arraySegment)
 {
 }
Пример #15
0
        public static async Task ReceiveAsync(this WebSocket webSocket, IWebSocketsClient client)
        {
            int currentMessageLength = 0;

            byte[] buffer       = new byte[1024 * 4];
            byte[] combinedData = Array.Empty <byte>();

            WebSocketReceiveResult        result = null;
            Task <WebSocketReceiveResult> receiveBeforeTheLoop = webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
            await receiveBeforeTheLoop.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    // TODO: how to log it from here
                }

                if (t.IsCompletedSuccessfully)
                {
                    result = t.Result;
                }
            });

            if (result == null)
            {
                // TODO: how to log it from here
                return;
            }

            while (result.MessageType != WebSocketMessageType.Close)
            {
                int newMessageLength = currentMessageLength + result.Count;
                if (newMessageLength > _maxPooledSize)
                {
                    throw new InvalidOperationException("Message too long");
                }

                byte[] newBytes = ArrayPool <byte> .Shared.Rent(newMessageLength);

                buffer.AsSpan(0, result.Count).CopyTo(newBytes.AsSpan(currentMessageLength, result.Count));
                if (!ReferenceEquals(combinedData, Array.Empty <byte>()))
                {
                    combinedData.AsSpan(0, currentMessageLength).CopyTo(newBytes.AsSpan(0, currentMessageLength));
                    ArrayPool <byte> .Shared.Return(combinedData);
                }

                combinedData         = newBytes;
                currentMessageLength = newMessageLength;

                if (result.EndOfMessage)
                {
                    Memory <byte> data = combinedData.AsMemory().Slice(0, currentMessageLength);
                    await client.ReceiveAsync(data);

                    currentMessageLength = 0;
                    ArrayPool <byte> .Shared.Return(combinedData);

                    combinedData = Array.Empty <byte>();
                }

                Task <WebSocketReceiveResult> receiveInTheLoop = webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                await receiveInTheLoop.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        result = null;
                        // TODO: how to log it from here
                    }

                    if (t.IsCompletedSuccessfully)
                    {
                        result = t.Result;
                    }
                });

                if (result == null)
                {
                    // TODO: how to log it from here
                    return;
                }
            }

            await webSocket.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.Empty, result.CloseStatusDescription, CancellationToken.None);
        }
Пример #16
0
        private async Task ProcessWSChat(AspNetWebSocketContext context)
        {
            try
            {
                WebSocket socket = context.WebSocket;

                Application App   = null;
                bool        isNew = true;
                if (!Apps.ContainsKey(SessionId))
                {
                    App = new Application();
                    Apps.Add(SessionId, App);
                }
                else
                {
                    isNew = false;
                    App   = Apps[SessionId];
                }

                Application.Current.Value = App;
                App.Socket = socket;

                while (true)
                {
                    try
                    {
                        ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[1024]);
                        WebSocketReceiveResult result = await socket.ReceiveAsync(
                            buffer, CancellationToken.None);

                        if (socket.State == WebSocketState.Open)
                        {
                            string userMessage = Encoding.UTF8.GetString(
                                buffer.Array, 0, result.Count);

                            var command = JsonConvert.DeserializeObject <WSEventArgs>(userMessage);

                            if (command.EventType == "openForm")
                            {
                                if (isNew)
                                {
                                    var formInfo = WebConfigurationManager.AppSettings["Form"];
                                    var type     = Type.GetType(formInfo);
                                    var form     = (Form)Activator.CreateInstance(type);
                                    await App.CreateDomain(form, SessionId, socket);
                                }
                                else
                                {
                                    await App.UpdateDomain(SessionId, socket);
                                }
                            }
                            else
                            {
                                await App.ProcessMessage(command);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (socket.State == WebSocketState.Open)
                        {
                            await socket.SendAsync(ex);

                            continue;
                        }
                        throw;
                    }
                }
            }
            catch
            {
                throw;
            }
        }
Пример #17
0
 protected override void OnMessageReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     Send(context, "HELLO");
 }
Пример #18
0
        /// <summary>
        /// socket监听方法
        /// </summary>
        /// <param name="arg">当前WebSocket上下文</param>
        /// <returns></returns>
        public async Task DoWork()
        {
            WebSocket _socket = await _Context.WebSockets.AcceptWebSocketAsync();

            this._socket = _socket;
            //监视相应
            while (true)
            {
                /*
                 * 接收客户端数据
                 */
                ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[bufferSize]);
                CancellationToken      token;
                WebSocketReceiveResult result = await _socket.ReceiveAsync(buffer, token);

                if (_socket.State == WebSocketState.Open)
                {
                    //当前数据大小
                    int curLength = Math.Min(buffer.Array.Length, result.Count);
                    //如果数据为json字符串,则为初次链接
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        try
                        {
                            string    msg   = Encoding.UTF8.GetString(buffer.Array, 0, curLength);
                            UploadMsg upMsg = msg.JsonDeserializer <UploadMsg>();
                            if (upMsg == null)
                            {
                                throw new Exception("服务器接收客户json数据失败");
                            }
                            if (string.IsNullOrEmpty(this.SubFolder) == false)
                            {
                                upMsg.SubFolder = this.SubFolder + "/" + upMsg.SubFolder;
                            }
                            _file = new UploadInfo(upMsg);
                            //接收文件信息成功
                            await SendSuccess("接收文件信息成功");
                        }
                        catch (Exception ex)
                        {
                            await SendError(ex);
                        }
                    }
                    else if (result.MessageType == WebSocketMessageType.Binary)
                    {
                        try
                        {
                            //保存上传数据追加到文件
                            AppendFile(buffer, curLength);
                            curSize += curLength;
                            //相应服务器保存文件大小
                            await SendSuccess("服务器保存进行中...", curLength);
                        }
                        catch (Exception ex)
                        {
                            await SendError(ex);
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }
Пример #19
0
        /// <summary>
        /// Called when this WebSockets Server receives a full message (EndOfMessage) form a WebSockets client.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="rxBuffer">The rx buffer.</param>
        /// <param name="rxResult">The rx result.</param>
        protected override void OnMessageReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
        {
            var          result = System.Text.Encoding.UTF8.GetString(rxBuffer);
            DataRequests feed   = (DataRequests)Enum.Parse(typeof(DataRequests), result);

            subscribers[feed].Add(context);
            if (!NeboContext.Instance.Polling[feed].Running)
            {
                NeboContext.Instance.Polling[feed].Start();
            }
        }
Пример #20
0
        private async Task <bool> ProcessConnectionAsync(
            CancellationToken cancellationToken,
            HttpListenerContext httpContext)
        {
            WebSocketContext webSocketContext = null;

            try
            {
                webSocketContext = await httpContext.AcceptWebSocketAsync(null);
            }
            catch
            {
                httpContext.Response.StatusCode = 500;
                httpContext.Response.Close();
                return(false);
            }
            WebSocket    webSocket = webSocketContext.WebSocket;
            MemoryStream ms        = new MemoryStream();
            IWebSocketConnectionHandler handler = this.createConnectionHandler();

            byte[] receiveBuffer = null;
            while (webSocket.State == WebSocketState.Open)
            {
                if (receiveBuffer == null)
                {
                    receiveBuffer = new byte[MaxBufferSize];
                }
                WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer), cancellationToken);

                if (receiveResult.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", cancellationToken);

                    continue;
                }
                if (receiveResult.EndOfMessage)
                {
                    await ms.WriteAsync(receiveBuffer, 0, receiveResult.Count, cancellationToken);

                    receiveBuffer = ms.ToArray();
                    ms.Dispose();
                    ms = new MemoryStream();
                }
                else
                {
                    await ms.WriteAsync(receiveBuffer, 0, receiveResult.Count, cancellationToken);

                    continue;
                }
                byte[] wsresponse = null;
                try
                {
                    wsresponse = await handler.ProcessWsMessageAsync(receiveBuffer, cancellationToken);
                }
                catch (Exception ex)
                {
                    wsresponse = await new ProtobufWsSerializer().SerializeAsync(
                        new WsResponseMessage
                    {
                        Result = WsResult.Error,
                        Value  = Encoding.UTF8.GetBytes(ex.Message)
                    });
                }

                await webSocket.SendAsync(
                    new ArraySegment <byte>(wsresponse),
                    WebSocketMessageType.Binary,
                    true,
                    cancellationToken);
            }
            return(true);
        }
Пример #21
0
 public abstract Task OnMessage(WebSocket socket, WebSocketReceiveResult result, byte[] buffer);
Пример #22
0
        protected async Task Connect()
        {
            Socket = SystemClientWebSocket.ConnectAsync(new Uri("ws://remote.natfrp.com:2333"), Source.Token).Result;
            await Socket.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary <string, object>
            {
                { "version", REMOTE_VERSION },
                { "type", "launcher" },
                { "token", Natfrp.Token },
                { "identifier", Identifier }
            }))), WebSocketMessageType.Text, true, Source.Token);

            Main.LogManager.Log(LogManager.CATEGORY_SERVICE_INFO, "Service", "RemoteManager: 远程管理已连接");

            var remote = new RemotePipeConnection();

            byte[] buffer = new byte[8192];
            while (!Source.IsCancellationRequested)
            {
                // Ensure message is complete
                int length = 0;
                WebSocketReceiveResult result = null;
                while (true)
                {
                    result = await Socket.ReceiveAsync(new ArraySegment <byte>(buffer, length, buffer.Length - length), Source.Token);

                    length += result.Count;
                    if (result.EndOfMessage)
                    {
                        break;
                    }
                    else if (length >= buffer.Length)
                    {
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 接收到过长消息, 已断开服务器连接, 将在稍后重连");
                        await Socket.CloseAsync(WebSocketCloseStatus.MessageTooBig, "消息过长", Source.Token);

                        return;
                    }
                }

                // Handle close message
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    switch (result.CloseStatus.Value)
                    {
                    case WebSocketCloseStatus.NormalClosure:
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_INFO, "Service", "RemoteManager: 服务端正常断开 [" + result.CloseStatusDescription + "] 将在稍后重连");
                        break;

                    case WebSocketCloseStatus.PolicyViolation:
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 服务器拒绝请求, 已停止远程管理功能: " + result.CloseStatusDescription);
                        Stop();
                        return;

                    case WebSocketCloseStatus.InternalServerError:
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 服务器内部错误, " + result.CloseStatusDescription);
                        break;

                    default:
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 未知错误 [" + result.CloseStatus + "], " + result.CloseStatusDescription);
                        break;
                    }
                    await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, Source.Token);

                    return;
                }

                // Hmm, ensure something unexpected won't crash the socket
                if (length < OVERHEAD)
                {
                    Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 收到过短的消息");
                    return;
                }

                // Process payload
                using (var ms = new MemoryStream())
                {
                    ms.Write(buffer, 0, OVERHEAD);
                    switch (buffer[0])
                    {
                    case 0x01: // Heartbeat
                        if (length != OVERHEAD)
                        {
                            Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 心跳包长度异常");
                            continue;
                        }
                        break;

                    case 0x02: // Remote Command
                        if (length < 24 + OVERHEAD)
                        {
                            Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 收到过短的指令");
                            continue;
                        }

                        byte[] nonce = new byte[24], data = new byte[length - nonce.Length - OVERHEAD];

                        Buffer.BlockCopy(buffer, OVERHEAD, nonce, 0, nonce.Length);
                        Buffer.BlockCopy(buffer, nonce.Length + OVERHEAD, data, 0, data.Length);

                        try
                        {
                            data = SecretBox.Open(data, nonce, EncryptKey);
                        }
                        catch
                        {
                            Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 指令解密失败, 原因可能为密钥错误, 如果您无故看到此错误请检查账户是否被盗");
                            break;
                        }
                        remote.Buffer = data;
                        Main.Pipe_DataReceived(remote, data.Length);

                        nonce = SecretBox.GenerateNonce();
                        ms.Write(nonce, 0, nonce.Length);

                        data = SecretBox.Create(remote.Buffer, nonce, EncryptKey);
                        ms.Write(data, 0, data.Length);
                        break;

                    default:
                        Main.LogManager.Log(LogManager.CATEGORY_SERVICE_WARNING, "Service", "RemoteManager: 收到未知消息");
                        continue;
                    }
                    await Socket.SendAsync(new ArraySegment <byte>(ms.ToArray()), WebSocketMessageType.Binary, true, Source.Token);
                }
            }
        }
Пример #23
0
        private void ProcessReceivingMessages()
        {
            Task.Run(async() =>
            {
                while (socket.State == WebSocketState.Open)
                {
                    ArraySegment <byte> buffer;
                    WebSocketReceiveResult result = null;
                    try
                    {
                        buffer = new ArraySegment <byte>(new byte[1024]);
                        result = await socket.ReceiveAsync(buffer, ReceiveTokenSource.Token);
                    }
                    catch (Exception ex)
                    {
                        socket      = null;
                        IsActive    = false;
                        IsConnected = false;
                        return;
                    }

                    if (result == null || result.Count == 0)
                    {
                        continue;
                    }

                    Kaenx.Konnect.Remote.MessageCodes code = (Konnect.Remote.MessageCodes)buffer.Array[0];

                    Debug.WriteLine("Got Remote Message: " + code);

                    //Check if assemby from this genügt
                    var q = from t in Assembly.LoadFrom("Kaenx.Konnect.dll").GetTypes()
                            where t.IsClass && t.IsNested == false && t.Namespace == "Kaenx.Konnect.Remote"
                            select t;

                    IRemoteMessage message = null;

                    foreach (Type t in q.ToList())
                    {
                        IRemoteMessage down = (IRemoteMessage)Activator.CreateInstance(t);
                        if (down != null && code == down.MessageCode)
                        {
                            message = down;
                            break;
                        }
                    }

                    if (message == null)
                    {
                        Debug.WriteLine("Unbekannte Nachricht: " + code);
                    }
                    try
                    {
                        message.Parse(buffer.Array.Take(result.Count).ToArray());
                    }
                    catch (Exception ex)
                    {
                    }

                    if (message is TunnelRequest && (message as TunnelRequest).Type == TunnelTypes.Connect)
                    {
                        TunnelRequest req = message as TunnelRequest;
                        KnxRemote rem     = new KnxRemote(Encoding.UTF8.GetString(req.Data), this);
                        await rem.Init(getUsbHandler);
                        int connId = await rem.ConnectToInterface(req);
                        Remotes.Add(connId, rem);
                        continue;
                    }


                    if (message.ToString().EndsWith("Response"))
                    {
                        Responses[message.SequenceNumber] = message;
                        OnResponse?.Invoke(message);
                    }
                    else
                    {
                        OnRequest?.Invoke(message);
                    }
                }

                Debug.WriteLine("Verbindung abgebrochen");
            });
        }
        private async Task Receive(WebSocket socket, Action <WebSocketReceiveResult, byte[]> handleMessage)
        {
            _logger.LogTrace("WebSocketManagerMiddleware.Receive(WebSocket, Action<WebSocketReceiveResult, byte[]>) started");

            ArraySegment <Byte>    buffer = new ArraySegment <byte>(new Byte[1024 * 4]);
            WebSocketReceiveResult result = null;

            while (socket.State == WebSocketState.Open || socket.State == WebSocketState.Connecting)
            {
                using (var ms = new MemoryStream())
                {
                    do
                    {
                        result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                        ms.Write(buffer.Array, buffer.Offset, result.Count);
                    }while (!result.EndOfMessage);

                    ms.Seek(0, SeekOrigin.Begin);

                    var bufferedData = ms.ToArray();

                    handleMessage(result, bufferedData);
                }
            }

            try
            {
                await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);

                var tokenId = _webSocketHandler.GetTokenId(socket);

                if (tokenId != null)
                {
                    await _webSocketHandler.RemoveWebSocketConnection(socket);
                }

                if (_webSocketHandler.GetTokenId(socket) == null)
                {
                    _logger.LogInformation("WebSocketConnectionManager.Receive -> All connections with id {" + tokenId + "} have been closed.");
                }
            }
            catch (WebSocketException ex)
            {
                var tokenId = _webSocketHandler.GetTokenId(socket);

                _logger.LogError("WebSocketConnectionManager.Receive -> Exception occured during connection closing. Connection id: " + tokenId + ". Exception message: " + ex.Message + ". WebSocket state - " + Enum.GetName(typeof(WebSocketState), socket.State));

                if (tokenId != null)
                {
                    await _webSocketHandler.RemoveWebSocketConnection(socket);
                }

                if (_webSocketHandler.GetTokenId(socket) == null)
                {
                    _logger.LogInformation("WebSocketConnectionManager.Receive -> All connections with id {" + tokenId + "} have been closed.");
                }

                throw new ArgumentException("WebSocketConnectionManager.Receive -> Exception occured during connection closing. Connection id: " + tokenId + ". Exception message: " + ex.Message);
            }

            _logger.LogTrace("WebSocketManagerMiddleware.Receive(WebSocket, Action<WebSocketReceiveResult, byte[]>) ended");
        }
 /// <summary>
 /// Receives and decompresses binary message from the WebSocket connection asynchronously.
 /// </summary>
 /// <param name="webSocket">The WebSocket representing the connection.</param>
 /// <param name="webSocketReceiveResult">The result of performing a first ReceiveAsync operation for this binary message.</param>
 /// <param name="receivePayloadBuffer">The application buffer which was the storage location for first ReceiveAsync operation and will be internally used for subsequent ones in context of this binary message.</param>
 /// <returns>The task object representing the asynchronous operation. The Result property on the task object returns a Byte array containing the received message.</returns>
 public virtual Task <byte[]> DecompressBinaryMessageAsync(WebSocket webSocket, WebSocketReceiveResult webSocketReceiveResult, byte[] receivePayloadBuffer)
 {
     return(ReceiveMessagePayloadAsync(webSocket, webSocketReceiveResult, receivePayloadBuffer));
 }
Пример #26
0
        static async void httpProcessRequest(HttpListenerContext httpListenerContext)
        {
            WebSocketContext webSocketContext = null;

            try
            {
                webSocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol : null);

                string ipAddress = httpListenerContext.Request.RemoteEndPoint.Address.ToString();
                //Console.WriteLine("Connected: IPAddress {0}", ipAddress);
            }
            catch //(Exception e)
            {
                httpListenerContext.Response.StatusCode = 500;
                httpListenerContext.Response.Close();
                //Console.WriteLine("Exception: {0}", e);
                return;
            }

            WebSocket webSocket = webSocketContext.WebSocket;

            lock (_lock) _clients.Add(webSocket);

            try
            {
                byte[] receiveBuffer = new byte[1024];
                while (webSocket.State == WebSocketState.Open)
                {
                    WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer), CancellationToken.None);

                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        lock (_lock) _clients.Remove(webSocket);
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
                    }
                    else
                    {
                        string message = Encoding.UTF8.GetString(receiveBuffer).TrimEnd('\0');
                        //fn_processClientCommand(message, webSocket);
                        //Dataflow.enqueue(new )
                        httpBroadCast(message);

                        ////byte[] bsend = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
                        ////var adata = new ArraySegment<byte>(bsend, 0, bsend.Length);
                        ////lock (_lock)
                        ////    foreach (var socket in _clients)
                        ////        socket.SendAsync(adata, WebSocketMessageType.Text, receiveResult.EndOfMessage, CancellationToken.None).Wait();
                        ////webSocket.SendAsync(adata, WebSocketMessageType.Text, receiveResult.EndOfMessage, CancellationToken.None).Wait();

                        //await webSocket.SendAsync(adata, WebSocketMessageType.Binary, receiveResult.EndOfMessage, CancellationToken.None);
                    }
                }
            }
            catch (Exception e)
            {
                //Console.WriteLine("Exception: {0}", e);
                //Console.WriteLine("Exception: {0}", e.Message);
                lock (_lock) _clients.Remove(webSocket);
            }
            finally
            {
                if (webSocket != null)
                {
                    webSocket.Dispose();
                }
            }
        }
Пример #27
0
        private async Task ProcessChat(AspNetWebSocketContext context)
        {
            WebSocket socket = context.WebSocket;
            string    user   = context.QueryString["user"].ToString();

            try
            {
                #region 用户添加连接池
                //第一次open时,添加到连接池中
                if (!CONNECT_POOL.ContainsKey(user))
                {
                    CONNECT_POOL.Add(user, socket);//不存在,添加
                }
                else
                if (socket != CONNECT_POOL[user])    //当前对象不一致,更新
                {
                    CONNECT_POOL[user] = socket;
                }
                #endregion

                #region 离线消息处理
                if (MESSAGE_POOL.ContainsKey(user))
                {
                    List <MessageInfo> msgs = MESSAGE_POOL[user];
                    foreach (MessageInfo item in msgs)
                    {
                        await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                    MESSAGE_POOL.Remove(user);//移除离线消息
                }
                #endregion

                string descUser = string.Empty;//目的用户
                while (true)
                {
                    if (socket.State == WebSocketState.Open)
                    {
                        ArraySegment <byte>    buffer = new ArraySegment <byte>(new byte[2048]);
                        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                        #region 消息处理(字符截取、消息转发)
                        try
                        {
                            #region 关闭Socket处理,删除连接池
                            if (socket.State != WebSocketState.Open)//连接关闭
                            {
                                if (CONNECT_POOL.ContainsKey(user))
                                {
                                    CONNECT_POOL.Remove(user);                                //删除连接池
                                }
                                break;
                            }
                            #endregion

                            string   userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
                            string[] msgList = userMsg.Split('|');
                            if (msgList.Length == 2)
                            {
                                if (msgList[0].Trim().Length > 0)
                                {
                                    descUser = msgList[0].Trim();//记录消息目的用户
                                }
                                buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(msgList[1]));
                            }
                            else
                            {
                                buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(userMsg));
                            }

                            if (CONNECT_POOL.ContainsKey(descUser))            //判断客户端是否在线
                            {
                                WebSocket destSocket = CONNECT_POOL[descUser]; //目的客户端
                                if (destSocket != null && destSocket.State == WebSocketState.Open)
                                {
                                    await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                                }
                            }
                            else
                            {
                                Task.Run(() =>
                                {
                                    if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
                                    {
                                        MESSAGE_POOL.Add(descUser, new List <MessageInfo>());
                                    }
                                    MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
                                });
                            }
                        }
                        catch (Exception exs)
                        {
                            //消息转发异常处理,本次消息忽略 继续监听接下来的消息
                        }
                        #endregion
                    }
                    else
                    {
                        break;
                    }
                }//while end
            }
            catch (Exception ex)
            {
                //整体异常处理
                if (CONNECT_POOL.ContainsKey(user))
                {
                    CONNECT_POOL.Remove(user);
                }
            }
        }
        public async Task CloseAsync_HandshakeStartedFromClient_Success(WebSocketCloseStatus status, string statusDescription, WebSocketCloseStatus expectedCloseStatus)
        {
            // [ActiveIssue("https://github.com/dotnet/runtime/issues/22011", TargetFrameworkMonikers.Netcoreapp)]
            string expectedStatusDescription = statusDescription;

            if (statusDescription == null)
            {
                expectedStatusDescription = string.Empty;
            }

            HttpListenerWebSocketContext context = await GetWebSocketContext();

            await ClientConnectTask;

            // Close the client output.
            Task clientCloseTask = Client.CloseOutputAsync(status, statusDescription, new CancellationToken());

            byte[] receivedServerBytes = new byte[10];
            Task <WebSocketReceiveResult> serverReceiveTask = context.WebSocket.ReceiveAsync(new ArraySegment <byte>(receivedServerBytes), new CancellationToken());

            await Task.WhenAll(clientCloseTask, serverReceiveTask);

            WebSocketReceiveResult serverResult = await serverReceiveTask;

            Assert.Equal(new byte[10], receivedServerBytes);
            Assert.Equal(expectedCloseStatus, serverResult.CloseStatus);
            Assert.Equal(statusDescription, serverResult.CloseStatusDescription);
            Assert.Equal(WebSocketMessageType.Close, serverResult.MessageType);
            Assert.True(serverResult.EndOfMessage);

            Assert.Equal(expectedCloseStatus, context.WebSocket.CloseStatus);
            Assert.Equal(statusDescription, context.WebSocket.CloseStatusDescription);
            Assert.Equal(WebSocketState.CloseReceived, context.WebSocket.State);

            // Trying to read if the server received a close handshake should fail.
            await Assert.ThrowsAsync <WebSocketException>(() => context.WebSocket.ReceiveAsync(new ArraySegment <byte>(receivedServerBytes), new CancellationToken()));

            // Close the server.
            Task serverCloseTask = context.WebSocket.CloseAsync(status, statusDescription, new CancellationToken());

            byte[] receivedClientBytes = new byte[10];
            Task <WebSocketReceiveResult> clientReceiveTask = Client.ReceiveAsync(new ArraySegment <byte>(receivedClientBytes), new CancellationToken());

            await Task.WhenAll(serverCloseTask, clientReceiveTask);

            WebSocketReceiveResult clientResult = await clientReceiveTask;

            Assert.Equal(new byte[10], receivedClientBytes);
            Assert.Equal(expectedCloseStatus, clientResult.CloseStatus);
            Assert.Equal(expectedStatusDescription, clientResult.CloseStatusDescription);
            Assert.Equal(WebSocketMessageType.Close, clientResult.MessageType);
            Assert.True(clientResult.EndOfMessage);

            Assert.Equal(expectedCloseStatus, context.WebSocket.CloseStatus);
            Assert.Equal(statusDescription, context.WebSocket.CloseStatusDescription);
            Assert.Equal(WebSocketState.Closed, context.WebSocket.State);

            // Trying to read or write if closed should fail.
            await Assert.ThrowsAsync <WebSocketException>(() => context.WebSocket.ReceiveAsync(new ArraySegment <byte>(receivedServerBytes), new CancellationToken()));

            await Assert.ThrowsAsync <WebSocketException>(() => context.WebSocket.SendAsync(new ArraySegment <byte>(receivedServerBytes), WebSocketMessageType.Binary, false, new CancellationToken()));

            // Trying to close again should be a nop.
            await context.WebSocket.CloseAsync(WebSocketCloseStatus.Empty, null, new CancellationToken());

            await context.WebSocket.CloseOutputAsync(WebSocketCloseStatus.Empty, null, new CancellationToken());
        }
Пример #29
0
    public static async void WsTraceRoute(HttpListenerContext ctx)
    {
        WebSocketContext wsc;
        WebSocket        ws;

        try {
            wsc = await ctx.AcceptWebSocketAsync(null);

            ws = wsc.WebSocket;
        } catch (WebSocketException ex) {
            ctx.Response.Close();
            Logging.Err(ex);
            return;
        }

        string sessionId = ctx.Request.Cookies["sessionid"]?.Value ?? null;

        if (sessionId is null)
        {
            ctx.Response.Close();
            return;
        }

        object send_lock = new object();

        try {
            while (ws.State == WebSocketState.Open)
            {
                byte[] buff = new byte[2048];
                WebSocketReceiveResult receiveResult = await ws.ReceiveAsync(new ArraySegment <byte>(buff), CancellationToken.None);

                if (!Session.CheckAccess(sessionId))   //check session
                {
                    ctx.Response.Close();
                    return;
                }

                if (receiveResult.MessageType == WebSocketMessageType.Close)
                {
                    await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);

                    break;
                }

                string hostname = Encoding.Default.GetString(buff, 0, receiveResult.Count);
                hostname = hostname.Trim();
                if (hostname.Length == 0)
                {
                    await ws.SendAsync(Strings.INV, WebSocketMessageType.Text, true, CancellationToken.None);

                    continue;
                }

                const short timeout = 2000; //2s
                const short ttl     = 30;

                List <string> list = new List <string>();

                new Thread(async() => {
                    List <IPAddress> ipList = new List <IPAddress>();
                    string lastAddress      = "";

                    using (System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping())
                        for (short i = 1; i < ttl; i++)
                        {
                            if (ws.State != WebSocketState.Open)
                            {
                                break;
                            }
                            string result = $"{hostname}{(char)127}";

                            try {
                                PingReply reply = p.Send(hostname, timeout, TRACE_ROUTE_BUFFER, new PingOptions(i, true));
                                if (reply.Status == IPStatus.Success || reply.Status == IPStatus.TtlExpired)
                                {
                                    if (lastAddress == reply.Address.ToString())
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        lastAddress = reply.Address.ToString();
                                    }

                                    result += $"{reply.Address}{(char)127}{reply.RoundtripTime}";
                                    ipList.Add(reply.Address);
                                }
                                else if (reply.Status == IPStatus.TimedOut)
                                {
                                    result += "Timed Out";
                                }

                                else
                                {
                                    break;
                                }
                            } catch (Exception ex) {
                                Logging.Err(ex);
                                break;
                            }

                            lock (send_lock) //once send per socket
                                ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(result), 0, result.Length), WebSocketMessageType.Text, true, CancellationToken.None);
                        }

                    List <Task <string> > tasks = new List <Task <string> >();
                    for (int j = 0; j < ipList.Count; j++)
                    {
                        tasks.Add(Dns.DnsLookupAsync(ipList[j]));
                    }
                    string[] hostnameArray = await Task.WhenAll(tasks);

                    string hostnames = $"[hostnames]{(char)127}{hostname}{(char)127}";
                    for (int i = 0; i < hostnameArray.Length; i++)
                    {
                        if (hostnameArray[i].Length > 0 && hostnameArray[i] != ipList[i].ToString())
                        {
                            hostnames += $"{ipList[i]}{(char)127}{hostnameArray[i]}{(char)127}";
                        }
                    }
                    if (hostnames.EndsWith(((char)127).ToString()))
                    {
                        hostnames = hostnames.Substring(0, hostnames.Length - 1);
                    }

                    lock (send_lock) {
                        ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(hostnames), 0, hostnames.Length), WebSocketMessageType.Text, true, CancellationToken.None);

                        string over = "over" + ((char)127).ToString() + hostname;
                        ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(over), 0, over.Length), WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                }).Start();
            }
        } catch (Exception ex) {
            Logging.Err(ex);
        }
    }
Пример #30
0
 private Task WebSocket_WebSocketClosed(object sender, WebSocketReceiveResult receiveResult, byte[] buffer, CancellationToken cancellation = default)
 {
     return(Task.CompletedTask);
 }
 public Task Receive(WebSocket socket, WebSocketReceiveResult result, byte[] buffer)
 {
     throw new NotImplementedException();
 }
Пример #32
0
        public async Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken)
        {
            int oldState = Interlocked.CompareExchange(ref _receiveState, ReceiveOne, ReceiveNone);

            if (oldState == ReceiveDisposed)
            {
                throw SessionWebSocket.NewDisposedException();
            }
            if (oldState == ReceiveCloseReceived)
            {
                throw new InvalidOperationException(ReceiverIsClosed);
            }
            if (oldState == ReceiveOne)
            {
                throw new InvalidOperationException(SimultaneousReceivesNotSupported);
            }

            try
            {
                await _receivesSem.WaitAsync(cancellationToken);

                if (_receiveState == ReceiveDisposed)
                {
                    throw SessionWebSocket.NewDisposedException();
                }
                PendingReceive receive;
                _receives.TryPeek(out receive);

                if (receive.Type == WebSocketMessageType.Text)
                {
                    try
                    {
                        int  length       = receive.TextMessage.Decode(buffer);
                        bool endOfMessage = receive.TextMessage.IsEmpty;
                        var  result       = new WebSocketReceiveResult(length, WebSocketMessageType.Text, endOfMessage);

                        if (endOfMessage)
                        {
                            _receives.TryDequeue(out receive);
                        }
                        else
                        {
                            // undo Wait
                            _receivesSem.Release();
                        }
                        return(result);
                    }
                    catch // Decode exception
                    {
                        _receives.TryDequeue(out receive);
                        throw;
                    }
                }
                else // (receive.Type == WebSocketMessageType.Close)
                {
                    var result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, receive.CloseStatus, receive.CloseStatusDescription);
                    Interlocked.CompareExchange(ref _receiveState, ReceiveCloseReceived, ReceiveOne);
                    _receives.TryDequeue(out receive);
                    return(result);
                }
            }
            finally
            {
                Interlocked.CompareExchange(ref _receiveState, ReceiveNone, ReceiveOne);
            }
        }
Пример #33
0
 protected override void OnFrameReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
 }
Пример #34
0
 protected override void OnFrameReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     $"Data frame: {Encoding.UTF8.GetString(rxBuffer)}".Debug();
 }