예제 #1
0
 public PendingSend(TaskCompletionSource<bool> tcs, WebSocketMessageType type, ArraySegment<byte> buffer, CancellationToken cancellationToken)
 {
     Type = type;
     _tcs = tcs;
     Buffer = buffer;
     CancellationToken = cancellationToken;
 }
예제 #2
0
        public virtual Task SendAsync(ArraySegment<byte> message, WebSocketMessageType messageType, bool endOfMessage = true)
        {
            if (WebSocket.State != WebSocketState.Open)
            {
                return TaskAsyncHelper.Empty;
            }

            var sendContext = new SendContext(this, message, messageType, endOfMessage);

            return _sendQueue.Enqueue(async state =>
            {
                var context = (SendContext)state;

                if (context.Handler.WebSocket.State != WebSocketState.Open)
                {
                    return;
                }

                try
                {
                    await context.Handler.WebSocket.SendAsync(context.Message, context.MessageType, context.EndOfMessage, CancellationToken.None);
                }
                catch (Exception ex)
                {
                    // Swallow exceptions on send
                    Trace.TraceError("Error while sending: " + ex);
                }
            },
            sendContext);
        }
 internal WebSocketMessageProperty(WebSocketContext context, string subProtocol, WebSocketMessageType incomingMessageType, ReadOnlyDictionary<string, object> properties)
 {
     this.context = context;
     this.subProtocol = subProtocol;
     this.messageType = incomingMessageType;
     this.properties = properties;
 }
        public override Task OnMessageReceived(ArraySegment<byte> message, WebSocketMessageType type)
        {
            if (this.MessageReceived != null)
                this.MessageReceived(this, new SocketMessage(this.Id, new UTF8Encoding().GetString(message.Array)));

            return base.OnMessageReceived(message, type);
        }
예제 #5
0
 public SendContext(ArraySegment<byte> buffer, bool endOfMessage, WebSocketMessageType type, CancellationToken cancelToken)
 {
     this.Buffer = buffer;
     this.EndOfMessage = endOfMessage;
     this.Type = type;
     this.CancelToken = cancelToken;
 }
 private void TestChatHanlder_OnReceive(WebSocket Socket, WebSocketMessageType Type, byte[] ReceiveMessage)
 {
     //並行廣播給所有使用者,也可以轉發給指定使用者
     Parallel.ForEach(WebSocketList, async socket => {
         await socket.SendAsync(new ArraySegment<byte>(ReceiveMessage), Type, true, CancellationToken.None);
     });
 }
 public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 client, WebSocketMessageType messageType, WebSocketExtensionFlags extensionFlags)
     : this(client, messageType)
 {
     ExtensionFlags.Rsv1 = extensionFlags.Rsv1;
     ExtensionFlags.Rsv2 = extensionFlags.Rsv2;
     ExtensionFlags.Rsv3 = extensionFlags.Rsv3;
 }
        internal static Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE GetWinHttpMessageType(WebSocketMessageType messageType, bool endOfMessage)
        {
            switch (messageType)
            {
                case WebSocketMessageType.Binary:
                    if (endOfMessage)
                    {
                        return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE;
                    }
                    else
                    {
                        return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE;
                    }

                case WebSocketMessageType.Text:
                    if (endOfMessage)
                    {
                        return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE;
                    }
                    else
                    {
                        return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE;
                    }

                case WebSocketMessageType.Close:
                    return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE;

                default:
                    Debug.Fail("Unknown WebSocketMessageType.");
                    return Interop.WinHttp.WINHTTP_WEB_SOCKET_BUFFER_TYPE.WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE;
            }
        }
예제 #9
0
 public Task SendAsync(
     ArraySegment<byte> bytes,
     WebSocketMessageType webSocketMessageType,
     bool endOfMessage,
     CancellationToken cancellationToken)
 {
     return this.socket.SendAsync(bytes, webSocketMessageType, endOfMessage, cancellationToken);
 }
 public Task SendAsync(
     ArraySegment<byte> bytes,
     WebSocketMessageType webSocketMessageType,
     bool endOfMessage,
     CancellationToken cancellationToken)
 {
     return Task.Run(() => this.socket.Send(new[] { bytes }), cancellationToken);
 }
예제 #11
0
		public WebSocketReceiveResult (int count,
		                               WebSocketMessageType messageType,
		                               bool endOfMessage,
		                               WebSocketCloseStatus? closeStatus,
		                               string closeStatusDescription)
		{
			throw new NotImplementedException ();
		}
        public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 webSocket, WebSocketMessageType messageType)
        {
            Guard.ParameterCannotBeNull(webSocket, "webSocket");

            _internalUsedBufferLength = 0;
            _messageType = messageType;
            _webSocket = webSocket;
        }
예제 #13
0
 public Task SendAsync(
     ArraySegment<byte> buffer,
     WebSocketMessageType messageType,
     bool endOfMessage,
     CancellationToken cancellationToken)
 {
     return _webSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken);
 }
예제 #14
0
 public Task SendAsync(
     ArraySegment<byte> buffer,
     WebSocketMessageType messageType,
     bool endOfMessage,
     CancellationToken cancellationToken)
 {
     throw new PlatformNotSupportedException(SR.net_WebSockets_UnsupportedPlatform);
 }
        public WebSocketMessageWriteRfc6455Stream(WebSocketRfc6455 webSocket, WebSocketMessageType messageType)
        {
            if (webSocket == null)
                throw new ArgumentNullException("webSocket");

            _internalUsedBufferLength = 0;
            _messageType = messageType;
            _webSocket = webSocket;
        }
 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);
 }
예제 #17
0
 public static int GetOpCode(WebSocketMessageType messageType)
 {
     switch (messageType)
     {
         case WebSocketMessageType.Text: return Constants.OpCodes.TextFrame;
         case WebSocketMessageType.Binary: return Constants.OpCodes.BinaryFrame;
         case WebSocketMessageType.Close: return Constants.OpCodes.CloseFrame;
         default: throw new NotImplementedException(messageType.ToString());
     }
 }
        public override WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType)
        {
            Connection.BeginWritting();
            WebSocketMessageWriteStream writer = new WebSocketMessageWriteRfc6455Stream(this, messageType);

            foreach (var extension in _extensions)
                writer = extension.ExtendWriter(writer);

            return writer;
        }
예제 #19
0
파일: Service.cs 프로젝트: tewarid/NetTools
        private Message CreateMessage(byte[] message,
            WebSocketMessageType type = WebSocketMessageType.Binary)
        {
            Message channelMessage = ByteStreamMessage.CreateMessage(new ArraySegment<byte>(message));

            channelMessage.Properties[webSocketMessageProperty] =
                new WebSocketMessageProperty { MessageType = type };

            return channelMessage;
        }
        public WebSocketMessageReadRfc6455Stream(WebSocketRfc6455 webSocket)
        {
            Guard.ParameterCannotBeNull(webSocket, "webSocket");

            _webSocket = webSocket;
            _messageType = (WebSocketMessageType)_webSocket.Connection.CurrentHeader.Flags.Option;
            _flags = GetExtensionFlags(_webSocket.Connection.CurrentHeader.Flags);
            _hasPendingFrames = !_webSocket.Connection.CurrentHeader.Flags.FIN;
            if (_webSocket.Connection.CurrentHeader.Flags.Option != WebSocketFrameOption.Binary && _webSocket.Connection.CurrentHeader.Flags.Option != WebSocketFrameOption.Text)
                throw new WebSocketException("WebSocketMessageReadNetworkStream can only start with a Text or Binary frame, not " + _webSocket.Connection.CurrentHeader.Flags.Option.ToString());
        }
예제 #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WebSocketReceiveResult" /> class.
        /// </summary>
        /// <param name="count">The count.</param>
        /// <param name="messageType">Type of the message.</param>
        /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
        public WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage)
        {
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            Count = count;
            EndOfMessage = endOfMessage;
            MessageType = messageType;
        }
예제 #22
0
        public Task Send(ArraySegment<byte> data, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancelToken)
        {
            var sendContext = new SendContext(data, endOfMessage, messageType, cancelToken);

            return this.mSendQueue.Enqueue(
                async s =>
                {
                    await this.mSendAsync(s.Buffer, MessageTypeEnumToOpCode(s.Type), s.EndOfMessage, s.CancelToken);
                },
                sendContext);
        }
        /// <summary>
        /// Sends data to the client
        /// </summary>
        /// <param name="buffer">Data to send</param>
        /// <param name="endOfMessage">End of the message?</param>
        /// <param name="type">Message type of the data</param>
        /// <returns>Task to send the data</returns>
        public Task SendAsync(ArraySegment<byte> buffer, bool endOfMessage, WebSocketMessageType type)
        {
            var sendContext = new SendContext { Buffer = buffer, EndOfMessage = endOfMessage, Type = type };

            return mSendQueue.Enqueue(
                async s =>
                    {
                        await mWebSocket.SendAsync(s.Buffer, s.Type, s.EndOfMessage, CancellationToken.None);
                    },
                sendContext);
        }
예제 #24
0
		public WebSocketReceiveResult (int count,
		                               WebSocketMessageType messageType,
		                               bool endOfMessage,
		                               WebSocketCloseStatus? closeStatus,
		                               string closeStatusDescription)
		{
			MessageType = messageType;
			CloseStatus = closeStatus;
			CloseStatusDescription = closeStatusDescription;
			Count = count;
			EndOfMessage = endOfMessage;
		}
        public override WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType)
        {
            if (!Connection.IsConnected)
                throw new WebSocketException("The connection is closed");

            Connection.BeginWritting();
            WebSocketMessageWriteStream writer = new WebSocketMessageWriteRfc6455Stream(this, messageType);

            foreach (var extension in _extensions)
                writer = extension.ExtendWriter(writer);

            return writer;
        }
        public override Task OnMessageReceived(ArraySegment<byte> message, WebSocketMessageType type)
        {
            if (message.Count > 0)
            {
                var bytes = new UTF8Encoding(true).GetString(message.Array, 0, message.Count);
                var streamEvent = JsonConvert.DeserializeObject<ProcessStreamEvent>(bytes);

                if (streamEvent.MessageType == "run" && streamEvent.ApiProcessSpec != null)
                {
                    runService.Run(this, streamEvent.ApiProcessSpec);
                }
            }

            return Task.Delay(0);
        }
        public WebSocketReceiveResult(int count, 
            WebSocketMessageType messageType, 
            bool endOfMessage, 
            Nullable<WebSocketCloseStatus> closeStatus, 
            string closeStatusDescription)
        {
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            this.Count = count;
            this.EndOfMessage = endOfMessage;
            this.MessageType = messageType;
            this.CloseStatus = closeStatus;
            this.CloseStatusDescription = closeStatusDescription;
        }
예제 #28
0
        internal Task SendAsync(byte[] message, WebSocketMessageType messageType)
        {
            if (_isClosed)
            {
                return TaskAsyncHelper.Empty;
            }

            return _sendQueue.Enqueue(() =>
            {
                if (_isClosed)
                {
                    return TaskAsyncHelper.Empty;
                }

                return WebSocket.SendAsync(new ArraySegment<byte>(message), messageType, true /* endOfMessage */, CancellationToken.None);
            });
        }
예제 #29
0
        public WebSocketReceiveResult(int count,
            WebSocketMessageType messageType,
            bool endOfMessage,
            WebSocketCloseStatus? closeStatus,
            string closeStatusDescription)
        {
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            Count = count;
            EndOfMessage = endOfMessage;
            MessageType = messageType;
            CloseStatus = closeStatus;
            CloseStatusDescription = closeStatusDescription;
        }
예제 #30
0
        public static async Task TestEcho(
            Uri server,
            WebSocketMessageType type,
            int timeOutMilliseconds,
            ITestOutputHelper output)
        {
            var cts = new CancellationTokenSource(timeOutMilliseconds);
            string message = "Hello WebSockets!";
            string closeMessage = "Good bye!";
            var receiveBuffer = new byte[100];
            var receiveSegment = new ArraySegment<byte>(receiveBuffer);

            using (ClientWebSocket cws = await GetConnectedWebSocket(server, timeOutMilliseconds, output))
            {
                output.WriteLine("TestEcho: SendAsync starting.");
                await cws.SendAsync(WebSocketData.GetBufferFromText(message), type, true, cts.Token);
                output.WriteLine("TestEcho: SendAsync done.");
                Assert.Equal(WebSocketState.Open, cws.State);

                output.WriteLine("TestEcho: ReceiveAsync starting.");
                WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cts.Token);
                output.WriteLine("TestEcho: ReceiveAsync done.");
                Assert.Equal(WebSocketState.Open, cws.State);
                Assert.Equal(message.Length, recvRet.Count);
                Assert.Equal(type, recvRet.MessageType);
                Assert.Equal(true, recvRet.EndOfMessage);
                Assert.Equal(null, recvRet.CloseStatus);
                Assert.Equal(null, recvRet.CloseStatusDescription);

                var recvSegment = new ArraySegment<byte>(receiveSegment.Array, receiveSegment.Offset, recvRet.Count);
                Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment));

                output.WriteLine("TestEcho: CloseAsync starting.");
                Task taskClose = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, closeMessage, cts.Token);
                Assert.True(
                    (cws.State == WebSocketState.Open) || (cws.State == WebSocketState.CloseSent) ||
                    (cws.State == WebSocketState.CloseReceived) || (cws.State == WebSocketState.Closed),
                    "State immediately after CloseAsync : " + cws.State);
                await taskClose;
                output.WriteLine("TestEcho: CloseAsync done.");
                Assert.Equal(WebSocketState.Closed, cws.State);
                Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus);
                Assert.Equal(closeMessage, cws.CloseStatusDescription);
            }
        }
예제 #31
0
        private async Task <bool> MessageWriteAsync(ClientMetadata client, byte[] data, WebSocketMessageType messageType)
        {
            try
            {
                #region Send-Message

                // Cannot have two simultaneous SendAsync calls so use a
                // semaphore to block the second until the first has completed

                await client.SendAsyncLock.WaitAsync(client.KillToken.Token);

                try
                {
                    await client.Ws.SendAsync(new ArraySegment <byte>(data, 0, data.Length),
                                              messageType, true, client.KillToken.Token);
                }
                finally
                {
                    client.SendAsyncLock.Release();
                }

                return(true);

                #endregion
            }
            catch (Exception e)
            {
                Log("*** MessageWriteAsync " + client.IpPort() + " disconnected due to exception " + e);
                return(false);
            }
        }
        private void _startReceiveTask()
        {
            Task.Run(async() =>
            {
                var token = _wsTokenSource.Token;

                // If cancelled, disconnect and get out
                if (token.IsCancellationRequested)
                {
                    await Disconnect();
                }
                else
                {
                    while (_ws.State == WebSocketState.Open)
                    {
                        var buffer = new byte[1024];
                        var bytes  = new List <byte>();
                        var str    = "";

                        // First read all the message bytes
                        WebSocketMessageType messageType = WebSocketMessageType.Close;
                        bool endOfMessage = false;
                        do
                        {
                            try
                            {
                                var result = await _ws.ReceiveAsync(new ArraySegment <byte>(buffer), token);
                                if (result != null)
                                {
                                    endOfMessage = result.EndOfMessage;
                                    var newBytes = new byte[result.Count];
                                    Array.Copy(buffer, newBytes, result.Count);
                                    bytes.AddRange(newBytes);
                                    messageType = result.MessageType;
                                }
                            }
                            catch (Exception e)
                            {
                                Logger.Error(e, "Exception processing message from web socket.");
                                endOfMessage = true;
                            }
                        } while (!endOfMessage && _ws.State == WebSocketState.Open);

                        // Now process the message
                        switch (messageType)
                        {
                        case WebSocketMessageType.Close:
                            await Disconnect();
                            break;

                        case WebSocketMessageType.Text:
                            str += Encoding.UTF8.GetString(buffer).TrimEnd('\0');
                            EmitMessage(new MessageEvent(str));
                            break;

                        case WebSocketMessageType.Binary:
                            EmitBinaryMessage(new BinaryMessageEvent(bytes.ToArray()));
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }

                return(Task.CompletedTask);
            }, _wsTokenSource.Token);
        }
예제 #33
0
 public WebSocketMessageProperty()
 {
     this.messageType = WebSocketDefaults.DefaultWebSocketMessageType;
 }
예제 #34
0
        public WebSocketReceiveResult Receive()
        {
            try
            {
                // we may receive control frames so reading needs to happen in an infinite loop
                while (true)
                {
                    // allow this operation to be cancelled from iniside OR outside this instance
                    WebSocketFrame frame = null;
                    try
                    {
                        frame = WebSocketFrameReader.Read(_stream, _receiveBuffer);
                        _logger("websocket.ReceivedFrame: " + frame.OpCode + ", " + frame.IsFinBitSet + ", " + frame.Count);
                    }
                    catch (InternalBufferOverflowException ex)
                    {
                        CloseOutputAutoTimeout(WebSocketCloseStatus.MessageTooBig, "Frame too large to fit in buffer. Use message fragmentation", ex);
                        throw;
                    }
                    catch (ArgumentOutOfRangeException ex)
                    {
                        CloseOutputAutoTimeout(WebSocketCloseStatus.ProtocolError, "Payload length out of range", ex);
                        throw;
                    }
                    catch (EndOfStreamException ex)
                    {
                        CloseOutputAutoTimeout(WebSocketCloseStatus.InvalidPayloadData, "Unexpected end of stream encountered", ex);
                        throw;
                    }
                    catch (OperationCanceledException ex)
                    {
                        CloseOutputAutoTimeout(WebSocketCloseStatus.EndpointUnavailable, "Operation cancelled", ex);
                        throw;
                    }
                    catch (Exception ex)
                    {
                        CloseOutputAutoTimeout(WebSocketCloseStatus.InternalServerError, "Error reading WebSocket frame", ex);
                        throw;
                    }

                    switch (frame.OpCode)
                    {
                    case WebSocketOpCode.ConnectionClose:
                        return(RespondToCloseFrame(frame, _receiveBuffer));

                    case WebSocketOpCode.Ping:
                        ArraySegment <byte> pingPayload = new ArraySegment <byte>(_receiveBuffer.Array, _receiveBuffer.Offset, frame.Count);
                        SendPong(pingPayload);
                        break;

                    case WebSocketOpCode.Pong:
                        ArraySegment <byte> pongBuffer = new ArraySegment <byte>(_receiveBuffer.Array, frame.Count, _receiveBuffer.Offset);
                        if (pongBuffer.Array.SequenceEqual(_pingPayload))
                        {
                        }
                        LastPingPong = DateTime.UtcNow;
                        NeedsPing    = true;
                        break;

                    case WebSocketOpCode.TextFrame:
                        if (!frame.IsFinBitSet)
                        {
                            // continuation frames will follow, record the message type Text
                            _continuationFrameMessageType = WebSocketMessageType.Text;
                        }
                        return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Text, frame.IsFinBitSet, _receiveBuffer));

                    case WebSocketOpCode.BinaryFrame:
                        if (!frame.IsFinBitSet)
                        {
                            // continuation frames will follow, record the message type Binary
                            _continuationFrameMessageType = WebSocketMessageType.Binary;
                        }
                        return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Binary, frame.IsFinBitSet, _receiveBuffer));

                    case WebSocketOpCode.ContinuationFrame:
                        return(new WebSocketReceiveResult(frame.Count, _continuationFrameMessageType, frame.IsFinBitSet, _receiveBuffer));

                    default:
                        Exception ex = new NotSupportedException($"Unknown WebSocket opcode {frame.OpCode}");
                        CloseOutputAutoTimeout(WebSocketCloseStatus.ProtocolError, ex.Message, ex);
                        throw ex;
                    }
                }
            }
            catch (Exception catchAll)
            {
                // Most exceptions will be caught closer to their source to send an appropriate close message (and set the WebSocketState)
                // However, if an unhandled exception is encountered and a close message not sent then send one here
                if (_state == WebSocketState.Open)
                {
                    CloseOutputAutoTimeout(WebSocketCloseStatus.InternalServerError, "Unexpected error reading from WebSocket", catchAll);
                }

                throw;
            }
        }
예제 #35
0
 public WebSocketMessage(object data, WebSocketMessageType messageType)
 {
     Data        = data;
     MessageType = messageType;
 }
 public WebSocketResponseEventArgs(WebSocketMessageType type, byte[] data)
 {
     MessageType = type;
     Data        = data;
 }
예제 #37
0
        static byte[] PrepareWebSocketHeader(int bufferLength, WebSocketMessageType webSocketMessageType)
        {
            byte[] octet;

            if (bufferLength < MediumSizeFrame)
            {
                // Handle small payloads and control frames
                octet = new byte[6];

                // Octet0
                octet[0] = PrepareOctet0(webSocketMessageType);

                // Octet 1
                octet[1] = (byte)(bufferLength | Mask);

                // Octets 2-5 (Masking Key)
                octet[2] = maskingKey[0];
                octet[3] = maskingKey[1];
                octet[4] = maskingKey[2];
                octet[5] = maskingKey[3];
            }
            else if (bufferLength <= UInt16.MaxValue)
            {
                // Handle medium payloads
                octet = new byte[8];

                // Octet 0
                octet[0] = PrepareOctet0(webSocketMessageType);

                // Octet 1
                octet[1] = MediumSizeFrame | Mask;

                // Octet 2-3 Payload Length
                octet[2] = (byte)((bufferLength >> 8) & 0x00FF);
                octet[3] = (byte)(bufferLength & 0x00FF);

                // Octets 4-7 (Masking Key)
                octet[4] = maskingKey[0];
                octet[5] = maskingKey[1];
                octet[6] = maskingKey[2];
                octet[7] = maskingKey[3];
            }
            else
            {
                // Handle large payloads
                octet = new byte[14];

                // Octet 0
                octet[0] = PrepareOctet0(webSocketMessageType);

                // Octet 1
                octet[1] = LargeSizeFrame | Mask;

                // Octet 2-9 Payload Length

                // ignore anything larger than a 32-bit number
                // octet[2] = octet[3] = octet[4] = octet[5] = 0; These are already set to 0
                octet[6] = (byte)((bufferLength >> 24) & 0x00FF);
                octet[7] = (byte)((bufferLength >> 16) & 0x00FF);
                octet[8] = (byte)((bufferLength >> 8) & 0x00FF);
                octet[9] = (byte)(bufferLength & 0x00FF);

                // Octets 10-13 (Masking Key)
                octet[10] = maskingKey[0];
                octet[11] = maskingKey[1];
                octet[12] = maskingKey[2];
                octet[13] = maskingKey[3];
            }

            return(octet);
        }
예제 #38
0
 public static void MessageReceived(ILogger logger, WebSocketMessageType type, int size, bool endOfMessage)
 {
     _messageReceived(logger, type, size, endOfMessage, null);
 }
예제 #39
0
 public Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken token)
 {
     return(mSocket.SendAsync(buffer, messageType, endOfMessage, token));
 }
 public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
예제 #41
0
 protected override Task SendAsync(WebSocket ws, ArraySegment <byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
 ws.SendAsync(arraySegment, messageType, endOfMessage, cancellationToken);
예제 #42
0
 public virtual ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
 MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> arraySegment) ?
 new ValueTask(SendAsync(arraySegment, messageType, endOfMessage, cancellationToken)) :
 SendWithArrayPoolAsync(buffer, messageType, endOfMessage, cancellationToken);
예제 #43
0
 public abstract Task SendAsync(ArraySegment <byte> buffer,
                                WebSocketMessageType messageType,
                                bool endOfMessage,
                                CancellationToken cancellationToken);
        public async Task SendAsync_InvalidMessageType_ThrowsArgumentNullException(WebSocketMessageType messageType)
        {
            HttpListenerWebSocketContext context = await GetWebSocketContext();

            await AssertExtensions.ThrowsAsync <ArgumentException>("messageType", () => context.WebSocket.SendAsync(new ArraySegment <byte>(), messageType, false, new CancellationToken()));
        }
예제 #45
0
 internal static async Task SendAsync(this WebSocket webSocket, byte[] buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => await webSocket.SendAsync(new ArraySegment <byte>(buffer), messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
예제 #46
0
        public override Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken)
        {
            EnsureWebSocketConnected();
            ValidateArraySegment(buffer);
            return(Task.Run(() => {
                EnsureWebSocketState(WebSocketState.Open, WebSocketState.CloseSent);

                bool isLast;
                long length;

                if (remaining == 0)
                {
                    // First read the two first bytes to know what we are doing next
                    connection.Read(req, headerBuffer, 0, 2);
                    isLast = (headerBuffer[0] >> 7) > 0;
                    var isMasked = (headerBuffer[1] >> 7) > 0;
                    int mask = 0;
                    currentMessageType = WireToMessageType((byte)(headerBuffer[0] & 0xF));
                    length = headerBuffer[1] & 0x7F;
                    int offset = 0;
                    if (length == 126)
                    {
                        offset = 2;
                        connection.Read(req, headerBuffer, 2, offset);
                        length = (headerBuffer[2] << 8) | headerBuffer[3];
                    }
                    else if (length == 127)
                    {
                        offset = 8;
                        connection.Read(req, headerBuffer, 2, offset);
                        length = 0;
                        for (int i = 2; i <= 9; i++)
                        {
                            length = (length << 8) | headerBuffer[i];
                        }
                    }

                    if (isMasked)
                    {
                        connection.Read(req, headerBuffer, 2 + offset, 4);
                        for (int i = 0; i < 4; i++)
                        {
                            var pos = i + offset + 2;
                            mask = (mask << 8) | headerBuffer[pos];
                        }
                    }
                }
                else
                {
                    isLast = (headerBuffer[0] >> 7) > 0;
                    currentMessageType = WireToMessageType((byte)(headerBuffer[0] & 0xF));
                    length = remaining;
                }

                if (currentMessageType == WebSocketMessageType.Close)
                {
                    state = WebSocketState.Closed;
                    var tmpBuffer = new byte[length];
                    connection.Read(req, tmpBuffer, 0, tmpBuffer.Length);
                    var closeStatus = (WebSocketCloseStatus)(tmpBuffer[0] << 8 | tmpBuffer[1]);
                    var closeDesc = tmpBuffer.Length > 2 ? Encoding.UTF8.GetString(tmpBuffer, 2, tmpBuffer.Length - 2) : string.Empty;
                    return new WebSocketReceiveResult((int)length, currentMessageType, isLast, closeStatus, closeDesc);
                }
                else
                {
                    var readLength = (int)(buffer.Count < length ? buffer.Count : length);
                    connection.Read(req, buffer.Array, buffer.Offset, readLength);
                    remaining = length - readLength;

                    return new WebSocketReceiveResult((int)readLength, currentMessageType, isLast && remaining == 0);
                }
            }));
        }
예제 #47
0
        /// <summary>
        /// Receive web socket result
        /// </summary>
        /// <param name="buffer">The buffer to copy data into</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>The web socket result details</returns>
        public override async Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken)
        {
            try
            {
                // we may receive control frames so reading needs to happen in an infinite loop
                while (true)
                {
                    // allow this operation to be cancelled from iniside OR outside this instance
                    using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_internalReadCts.Token, cancellationToken))
                    {
                        WebSocketFrame frame = null;
                        try
                        {
                            frame = await WebSocketFrameReader.ReadAsync(_stream, buffer, linkedCts.Token);

                            Events.Log.ReceivedFrame(_guid, frame.OpCode, frame.IsFinBitSet, frame.Count);
                        }
                        catch (InternalBufferOverflowException ex)
                        {
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.MessageTooBig, "Frame too large to fit in buffer. Use message fragmentation", ex);

                            throw;
                        }
                        catch (ArgumentOutOfRangeException ex)
                        {
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.ProtocolError, "Payload length out of range", ex);

                            throw;
                        }
                        catch (EndOfStreamException ex)
                        {
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InvalidPayloadData, "Unexpected end of stream encountered", ex);

                            throw;
                        }
                        catch (OperationCanceledException ex)
                        {
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.EndpointUnavailable, "Operation cancelled", ex);

                            throw;
                        }
                        catch (Exception ex)
                        {
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InternalServerError, "Error reading WebSocket frame", ex);

                            throw;
                        }

                        switch (frame.OpCode)
                        {
                        case WebSocketOpCode.ConnectionClose:
                            return(await RespondToCloseFrame(frame, buffer, linkedCts.Token));

                        case WebSocketOpCode.Ping:
                            ArraySegment <byte> pingPayload = new ArraySegment <byte>(buffer.Array, buffer.Offset, frame.Count);
                            await SendPongAsync(pingPayload, linkedCts.Token);

                            break;

                        case WebSocketOpCode.Pong:
                            ArraySegment <byte> pongBuffer = new ArraySegment <byte>(buffer.Array, frame.Count, buffer.Offset);
                            Pong?.Invoke(this, new PongEventArgs(pongBuffer));
                            break;

                        case WebSocketOpCode.TextFrame:
                            if (!frame.IsFinBitSet)
                            {
                                // continuation frames will follow, record the message type Text
                                _continuationFrameMessageType = WebSocketMessageType.Text;
                            }
                            return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Text, frame.IsFinBitSet));

                        case WebSocketOpCode.BinaryFrame:
                            if (!frame.IsFinBitSet)
                            {
                                // continuation frames will follow, record the message type Binary
                                _continuationFrameMessageType = WebSocketMessageType.Binary;
                            }
                            return(new WebSocketReceiveResult(frame.Count, WebSocketMessageType.Binary, frame.IsFinBitSet));

                        case WebSocketOpCode.ContinuationFrame:
                            return(new WebSocketReceiveResult(frame.Count, _continuationFrameMessageType, frame.IsFinBitSet));

                        default:
                            Exception ex = new NotSupportedException($"Unknown WebSocket opcode {frame.OpCode}");
                            await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.ProtocolError, ex.Message, ex);

                            throw ex;
                        }
                    }
                }
            }
            catch (Exception catchAll)
            {
                // Most exceptions will be caught closer to their source to send an appropriate close message (and set the WebSocketState)
                // However, if an unhandled exception is encountered and a close message not sent then send one here
                if (_state == WebSocketState.Open)
                {
                    await CloseOutputAutoTimeoutAsync(WebSocketCloseStatus.InternalServerError, "Unexpected error reading from WebSocket", catchAll);
                }

                throw;
            }
        }
예제 #48
0
 public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
 {
     return(_sendAsync(buffer, EnumToOpCode(messageType), endOfMessage, cancellationToken));
 }
예제 #49
0
 public Task Send(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken?cancellationToken = null)
 => _w?.SendAsync(buffer, messageType, endOfMessage, cancellationToken ?? CancellationToken.None)
 ?? throw new ObjectDisposedException(nameof(_w));
예제 #50
0
 public Task SendAsync(ArraySegment <byte> data, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancel)
 {
     return(mSendAsync(data, ConvertMessageTypeToInt(messageType), endOfMessage, cancel));
 }
예제 #51
0
 public virtual ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, WebSocketMessageFlags messageFlags, CancellationToken cancellationToken = default)
 {
     return(SendAsync(buffer, messageType, messageFlags.HasFlag(WebSocketMessageFlags.EndOfMessage), cancellationToken));
 }
예제 #52
0
 internal WebSocketMessageProperty(WebSocketContext context, string subProtocol, WebSocketMessageType incomingMessageType, ReadOnlyDictionary <string, object> properties)
 {
     WebSocketContext = context;
     SubProtocol      = subProtocol;
     MessageType      = incomingMessageType;
     this.properties  = properties;
 }
예제 #53
0
        /// <summary>
        /// Sends the async.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <param name="type">The type.</param>
        /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken)
        {
            UserContext.Send(bytes);

            return(_cachedTask);
        }
 public ValueWebSocketReceiveResult GetResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string?closeDescription) =>
 new ValueWebSocketReceiveResult(count, messageType, endOfMessage);     // closeStatus/closeDescription are ignored
예제 #55
0
        public static async Task <WebSocketMessage> ReadMessageAsync(WebSocket webSocket, int bufferSize, int?maxMessageSize, CancellationToken disconnectToken)
        {
            WebSocketMessage message;

            // Read the first time with an empty array
            WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(_emptyArraySegment, disconnectToken).PreserveCultureNotContext();

            if (TryGetMessage(receiveResult, null, out message))
            {
                return(message);
            }

            var buffer = new byte[bufferSize];

            // Now read with the real buffer
            var arraySegment = new ArraySegment <byte>(buffer);

            receiveResult = await webSocket.ReceiveAsync(arraySegment, disconnectToken).PreserveCultureNotContext();

            if (TryGetMessage(receiveResult, buffer, out message))
            {
                return(message);
            }
            else
            {
                // for multi-fragment messages, we need to coalesce
                ByteBuffer bytebuffer = new ByteBuffer(maxMessageSize);
                bytebuffer.Append(BufferSliceToByteArray(buffer, receiveResult.Count));
                WebSocketMessageType originalMessageType = receiveResult.MessageType;

                while (true)
                {
                    // loop until an error occurs or we see EOF
                    receiveResult = await webSocket.ReceiveAsync(arraySegment, disconnectToken).PreserveCultureNotContext();

                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        return(WebSocketMessage.CloseMessage);
                    }

                    if (receiveResult.MessageType != originalMessageType)
                    {
                        throw new InvalidOperationException("Incorrect message type");
                    }

                    bytebuffer.Append(BufferSliceToByteArray(buffer, receiveResult.Count));

                    if (receiveResult.EndOfMessage)
                    {
                        switch (receiveResult.MessageType)
                        {
                        case WebSocketMessageType.Binary:
                            return(new WebSocketMessage(bytebuffer.GetByteArray(), WebSocketMessageType.Binary));

                        case WebSocketMessageType.Text:
                            return(new WebSocketMessage(bytebuffer.GetString(), WebSocketMessageType.Text));

                        default:
                            throw new InvalidOperationException("Unknown message type");
                        }
                    }
                }
            }
        }
 public override ValueTask SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
 {
     return(SendPrivateAsync(buffer, messageType, endOfMessage, cancellationToken));
 }
예제 #57
0
 public abstract WebSocketMessageWriteStream CreateMessageWriter(WebSocketMessageType messageType);
예제 #58
0
        private async Task <bool> MessageWriteAsync(byte[] data, WebSocketMessageType msgType, CancellationToken token)
        {
            bool disconnectDetected = false;

            using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_Token, token))
            {
                try
                {
                    if (_ClientWs == null || _ClientWs.State != WebSocketState.Open)
                    {
                        Logger?.Invoke(_Header + "not connected");
                        disconnectDetected = true;
                        return(false);
                    }

                    await _SendLock.WaitAsync(_Token);

                    try
                    {
                        await _ClientWs.SendAsync(new ArraySegment <byte>(data, 0, data.Length), msgType, true, token);
                    }
                    finally
                    {
                        _SendLock.Release();
                    }

                    _Stats.IncrementSentMessages();
                    _Stats.AddSentBytes(data.Length);

                    return(true);
                }
                catch (TaskCanceledException)
                {
                    if (_Token.IsCancellationRequested)
                    {
                        Logger?.Invoke(_Header + "canceled");
                        disconnectDetected = true;
                    }
                    else if (token.IsCancellationRequested)
                    {
                        Logger?.Invoke(_Header + "message send canceled");
                    }

                    return(false);
                }
                catch (OperationCanceledException)
                {
                    if (_Token.IsCancellationRequested)
                    {
                        Logger?.Invoke(_Header + "canceled");
                        disconnectDetected = true;
                    }
                    else if (token.IsCancellationRequested)
                    {
                        Logger?.Invoke(_Header + "message send canceled");
                    }

                    return(false);
                }
                catch (WebSocketException)
                {
                    Logger?.Invoke(_Header + "websocket disconnected");
                    disconnectDetected = true;
                    return(false);
                }
                catch (ObjectDisposedException)
                {
                    Logger?.Invoke(_Header + "disposed");
                    disconnectDetected = true;
                    return(false);
                }
                catch (SocketException)
                {
                    Logger?.Invoke(_Header + "socket disconnected");
                    disconnectDetected = true;
                    return(false);
                }
                catch (InvalidOperationException)
                {
                    Logger?.Invoke(_Header + "disconnected due to invalid operation");
                    disconnectDetected = true;
                    return(false);
                }
                catch (IOException)
                {
                    Logger?.Invoke(_Header + "IO disconnected");
                    disconnectDetected = true;
                    return(false);
                }
                catch (Exception e)
                {
                    Logger?.Invoke(_Header + "exception: " + Environment.NewLine + e.ToString());
                    disconnectDetected = true;
                    return(false);
                }
                finally
                {
                    if (disconnectDetected)
                    {
                        Dispose();
                        ServerDisconnected?.Invoke(this, EventArgs.Empty);
                    }
                }
            }
        }
예제 #59
0
 protected abstract Task SendAsync(WebSocket ws, ArraySegment <byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken);
예제 #60
0
 public override Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage,
                                CancellationToken cancellationToken)
 {
     ThrowIfNotConnected();
     return(_innerWebSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken));
 }