public static async Task RunSample()
            {
                ClientWebSocket websocket = new ClientWebSocket();

                string url = "ws://localhost:5000/";

                Console.WriteLine("Connecting to: " + url);
                await websocket.ConnectAsync(new Uri(url), CancellationToken.None);

                string message = "Hello World";

                Console.WriteLine("Sending message: " + message);
                byte[] messageBytes = Encoding.UTF8.GetBytes(message);
                await websocket.SendAsync(new ArraySegment <byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);

                byte[] incomingData = new byte[1024];
                System.Net.WebSockets.WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment <byte>(incomingData), CancellationToken.None);

                if (result.CloseStatus.HasValue)
                {
                    Console.WriteLine("Closed; Status: " + result.CloseStatus + ", " + result.CloseStatusDescription);
                }
                else
                {
                    Console.WriteLine("Received message: " + Encoding.UTF8.GetString(incomingData, 0, result.Count));
                }
            }
示例#2
0
 private static void GetMessage(Tuple<int, WebSocket> connection, WebSocketReceiveResult result, ArraySegment<byte> bytes)
 {
     var connectionId = connection.Item1;
     var webSocket = connection.Item2;
     var message = Encoding.UTF8.GetString(bytes.Array, 0, result.Count);
     Broadcast(message, connectionId, result.EndOfMessage);
 }
示例#3
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 session = this.WebServer.GetSession(context);
     foreach (var ws in this.WebSockets)
     {
         if (ws != context)
             this.Send(ws, Encoding.UTF8.GetString(rxBuffer));
     }
 }
示例#4
0
        private static DataTransmission <T> ParseIncomingData <T>(WS.WebSocketReceiveResult retrival)
        {
            var buffer = new byte[1024 * 4];

            string[] data = Encoding.UTF8.GetString(new ArraySegment <byte>(buffer, 0, retrival.Count).ToArray()).Split('=');
            return(new DataTransmission <T>
            {
                MessageType = data[0],
                Message = JsonConvert.DeserializeObject <T>(data[1])
            });
        }
示例#5
0
        private async Task receiveLoop()
        {
            byte[] buffer = new byte[2048];
            while (true)
            {
                string json = string.Empty;
                try
                {
                    if (ws == null)
                    {
                        return;
                    }
                    if (ws.State != System.Net.WebSockets.WebSocketState.Open)
                    {
                        OnClose?.Invoke("");
                        return;
                    }
                    System.Net.WebSockets.WebSocketReceiveResult result = await ws.ReceiveAsync(new ArraySegment <byte>(buffer), src.Token);

                    json = Encoding.UTF8.GetString(buffer.Take(result.Count).ToArray());
                    var message = JsonConvert.DeserializeObject <SocketMessage>(json);
                    if (message != null)
                    {
                        _receiveQueue.Add(message);
                    }
                    await ProcessQueue();

                    errorcounter = 0;
                }
                catch (Exception ex)
                {
                    if (ws.State != System.Net.WebSockets.WebSocketState.Open)
                    {
                        OnClose?.Invoke(ex.Message);
                    }
                    else
                    {
                        errorcounter++;
                        Log.Error(json);
                        Log.Error(ex, "");
                        await Task.Delay(3000);

                        await this.Close();

                        //if(errorcounter > 10)
                        //{
                        //    errorcounter = 0;
                        //    await this.Close();
                        //}
                    }
                }
            }
        }
示例#6
0
    private async System.Threading.Tasks.Task <Response> ReceiveMessage()
    {
        // Receive one web socket message
        System.Collections.Generic.List <System.Collections.Generic.IEnumerable <byte> > segments = new System.Collections.Generic.List <System.Collections.Generic.IEnumerable <byte> >();

        try
        {
            while (true)
            {
                byte[] buffer  = new byte[4096];
                var    segment = new System.ArraySegment <byte>(buffer, 0, buffer.Length);
                System.Net.WebSockets.WebSocketReceiveResult rcvResult = await ws.ReceiveAsync(segment, stopServerTokenSource.Token);

                // Accumulate the byte arrays in a list, we will join them later
                segments.Add(segment.Skip(segment.Offset).Take(rcvResult.Count));

                if (rcvResult.EndOfMessage)
                {
                    break;
                }
            }
        }
        catch (System.Net.WebSockets.WebSocketException e)
        {
            throw e.InnerException;
        }
        catch (System.Exception)
        {
            throw new ErrorException("Error receiving response from server.");
        }

        try
        {
            byte[] bytes = segments.SelectMany(t => t).ToArray <byte>();
            string msg   = System.Text.Encoding.UTF8.GetString(bytes);
            return(Parse(msg));
        }
        catch (ErrorException e)
        {
            // Dispatch already built error
            throw e;
        }
        catch (System.Exception)
        {
            throw new ErrorException("Error while parsing response from server.");
        }
    }
        private static bool TryGetMessage(WebSocketReceiveResult receiveResult, byte[] buffer, out WebSocketMessage message)
        {
            message = null;

            if (receiveResult.MessageType == WebSocketMessageType.Close)
            {
                message = WebSocketMessage.CloseMessage;
            }
            else if (receiveResult.EndOfMessage)
            {
                // we anticipate that single-fragment messages will be common, so we optimize for them
                switch (receiveResult.MessageType)
                {
                    case WebSocketMessageType.Binary:
                        if (buffer == null)
                        {
                            message = WebSocketMessage.EmptyBinaryMessage;
                        }
                        else
                        {
                            message = new WebSocketMessage(BufferSliceToByteArray(buffer, receiveResult.Count), WebSocketMessageType.Binary);
                        }
                        break;
                    case WebSocketMessageType.Text:
                        if (buffer == null)
                        {
                            message = WebSocketMessage.EmptyTextMessage;
                        }
                        else
                        {
                            message = new WebSocketMessage(BufferSliceToString(buffer, receiveResult.Count), WebSocketMessageType.Text);
                        }
                        break;
                    default:
                        throw new InvalidOperationException("Unknown message type");
                }
            }

            return message != null;
        }
示例#8
0
 public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     ThrowIfInputClosed();
     ValidateSegment(buffer);
     // TODO: InvalidOperationException if any receives are currently in progress.
     
     Message receiveMessage = _receiveMessage;
     _receiveMessage = null;
     if (receiveMessage == null)
     {
         receiveMessage = await _receiveBuffer.ReceiveAsync(cancellationToken);
     }
     if (receiveMessage.MessageType == WebSocketMessageType.Close)
     {
         _closeStatus = receiveMessage.CloseStatus;
         _closeStatusDescription = receiveMessage.CloseStatusDescription ?? string.Empty;
         var result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, _closeStatus, _closeStatusDescription);
         if (_state == WebSocketState.Open)
         {
             _state = WebSocketState.CloseReceived;
         }
         else if (_state == WebSocketState.CloseSent)
         {
             _state = WebSocketState.Closed;
             Close();
         }
         return result;
     }
     else
     {
         int count = Math.Min(buffer.Count, receiveMessage.Buffer.Count);
         bool endOfMessage = count == receiveMessage.Buffer.Count;
         Array.Copy(receiveMessage.Buffer.Array, receiveMessage.Buffer.Offset, buffer.Array, buffer.Offset, count);
         if (!endOfMessage)
         {
             receiveMessage.Buffer = new ArraySegment<byte>(receiveMessage.Buffer.Array, receiveMessage.Buffer.Offset + count, receiveMessage.Buffer.Count - count);
             _receiveMessage = receiveMessage;
         }
         endOfMessage = endOfMessage && receiveMessage.EndOfMessage;
         return new WebSocketReceiveResult(count, receiveMessage.MessageType, endOfMessage);
     }
 }
示例#9
0
        private static Tuple<bool, string> GetMessage(Tuple<int, WebSocket> connection, WebSocketReceiveResult result, ArraySegment<byte> bytes, string messageAccumulator)
        {
            var connectionId = connection.Item1;
            var webSocket = connection.Item2;
            var message = Encoding.UTF8.GetString(bytes.Array, 0, result.Count);

            return new Tuple<bool, string>(result.EndOfMessage, messageAccumulator + message);
        }
示例#10
0
 /// <summary>
 /// Called when this WebSockets Server receives a message frame regardless if the frame represents the EndOfMessage.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="rxBuffer">The rx buffer.</param>
 /// <param name="rxResult">The rx result.</param>
 protected override void OnFrameReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     return;
 }
示例#11
0
        public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            ThrowIfInputClosed();
            ValidateSegment(buffer);
            // TODO: InvalidOperationException if any receives are currently in progress.

            // No active frame. Loop because we may be discarding ping/pong frames.
            while (_frameInProgress == null)
            {
                await ReadNextFrameAsync(cancellationToken);
            }

            int opCode = _frameInProgress.OpCode;

            if (opCode == Constants.OpCodes.CloseFrame)
            {
                return await ProcessCloseFrameAsync(cancellationToken);
            }

            // Handle fragmentation, remember the first frame type
            if (opCode == Constants.OpCodes.ContinuationFrame)
            {
                if (!_firstDataOpCode.HasValue)
                {
                    await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid continuation frame", cancellationToken);
                }
                opCode = _firstDataOpCode.Value;
            }
            else
            {
                _firstDataOpCode = opCode;
            }

            // Make sure there's at least some data in the buffer
            int bytesToBuffer = (int)Math.Min((long)_receiveBuffer.Length, _frameBytesRemaining);
            await EnsureDataAvailableOrReadAsync(bytesToBuffer, cancellationToken);

            // Copy buffered data to the users buffer
            int bytesToRead = (int)Math.Min((long)buffer.Count, _frameBytesRemaining);
            int bytesToCopy = Math.Min(bytesToRead, _receiveBufferBytes);
            Array.Copy(_receiveBuffer, _receiveBufferOffset, buffer.Array, buffer.Offset, bytesToCopy);

            if (_unmaskInput)
            {
                // _frameInProgress.Masked == _unmaskInput already verified
                Utilities.MaskInPlace(_frameInProgress.MaskKey, ref _dataUnmaskOffset, new ArraySegment<byte>(buffer.Array, buffer.Offset, bytesToCopy));
            }

            WebSocketReceiveResult result;
            WebSocketMessageType messageType = Utilities.GetMessageType(opCode);

            if (messageType == WebSocketMessageType.Text
                && !Utilities.TryValidateUtf8(new ArraySegment<byte>(buffer.Array, buffer.Offset, bytesToCopy), _frameInProgress.Fin, _incomingUtf8MessageState))
            {
                await SendErrorAbortAndThrow(WebSocketCloseStatus.InvalidPayloadData, "Invalid UTF-8", cancellationToken);
            }

            if (bytesToCopy == _frameBytesRemaining)
            {
                result = new WebSocketReceiveResult(bytesToCopy, messageType, _frameInProgress.Fin);
                if (_frameInProgress.Fin)
                {
                    _firstDataOpCode = null;
                }
                _frameInProgress = null;
                _dataUnmaskOffset = 0;
            }
            else
            {
                result = new WebSocketReceiveResult(bytesToCopy, messageType, false);
            }

            _frameBytesRemaining -= bytesToCopy;
            _receiveBufferBytes -= bytesToCopy;
            _receiveBufferOffset += bytesToCopy;

            return result;
        }
示例#12
0
        private void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            using (DataReader reader = args.GetDataReader())
            {
                uint dataAvailable;
                while ((dataAvailable = reader.UnconsumedBufferLength) > 0)
                {
                    ArraySegment<byte> buffer;
                    try
                    {
                        buffer = _receiveAsyncBufferTcs.Task.GetAwaiter().GetResult();
                    }
                    catch (OperationCanceledException) // Caused by Abort call on WebSocket
                    {
                        return;
                    }
                    
                    _receiveAsyncBufferTcs = new TaskCompletionSource<ArraySegment<byte>>();
                    WebSocketMessageType messageType;
                    if (args.MessageType == SocketMessageType.Binary)
                    {
                        messageType = WebSocketMessageType.Binary;
                    }
                    else
                    {
                        messageType = WebSocketMessageType.Text;
                    }

                    bool endOfMessage = false;
                    uint readCount = Math.Min(dataAvailable, (uint) buffer.Count);
                    var dataBuffer = reader.ReadBuffer(readCount);
                    // Safe to cast readCount to int as the maximum value that readCount can be is buffer.Count.
                    dataBuffer.CopyTo(0, buffer.Array, buffer.Offset, (int) readCount);
                    if (dataAvailable == readCount)
                    {
                        endOfMessage = true;
                    }

                    WebSocketReceiveResult recvResult = new WebSocketReceiveResult((int) readCount, messageType,
                        endOfMessage);
                    _webSocketReceiveResultTcs.TrySetResult(recvResult);
                }
            }
        }
示例#13
0
 /// <summary>
 /// Called when this WebSockets Server receives a message frame regardless if the frame represents the EndOfMessage.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="rxBuffer">The rx buffer.</param>
 /// <param name="rxResult">The rx result.</param>
 protected override void OnFrameReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     // don't process partial frames
     return;
 }
            Message PrepareMessage(WebSocketReceiveResult result, byte[] buffer, int count)
            {
                if (result.MessageType != WebSocketMessageType.Close)
                {
                    Message message;
                    if (_useStreaming)
                    {
                        using (var wrappedStream = new MaxMessageSizeStream(
                            new TimeoutStream(
                                new WebSocketStream(
                                    this,
                                    new ArraySegment<byte>(buffer, 0, count),
                                    _webSocket,
                                    result.EndOfMessage,
                                    _bufferManager,
                                    _defaultTimeouts.CloseTimeout),
                                _defaultTimeouts.ReceiveTimeout),
                            _maxReceivedMessageSize))
                        {
                            message = _encoder.ReadMessage(wrappedStream, _maxBufferSize);
                        }
                    }
                    else
                    {
                        ArraySegment<byte> bytes = new ArraySegment<byte>(buffer, 0, count);
                        message = _encoder.ReadMessage(bytes, _bufferManager);
                    }

                    if (message.Version.Addressing != AddressingVersion.None || !_localAddress.IsAnonymous)
                    {
                        _localAddress.ApplyTo(message);
                    }

                    if (message.Version.Addressing == AddressingVersion.None && message.Headers.Action == null)
                    {
                        if (result.MessageType == WebSocketMessageType.Binary)
                        {
                            message.Headers.Action = WebSocketTransportSettings.BinaryMessageReceivedAction;
                        }
                        else
                        {
                            // WebSocketMesssageType should always be binary or text at this moment. The layer below us will help protect this.
                            Fx.Assert(result.MessageType == WebSocketMessageType.Text, "result.MessageType must be WebSocketMessageType.Text.");
                            message.Headers.Action = WebSocketTransportSettings.TextMessageReceivedAction;
                        }
                    }

                    return message;
                }

                return null;
            }
示例#15
0
        private void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            // GetDataReader() throws an exception when either:
            // (1) The underlying TCP connection is closed prematurely (e.g., FIN/RST received without sending/receiving a WebSocket Close frame).
            // (2) The server sends invalid data (e.g., corrupt HTTP headers or a message exceeding the MaxMessageSize).
            //
            // In both cases, the appropriate thing to do is to close the socket, as we have reached an unexpected state in
            // the WebSocket protocol.
            try
            {
                using (DataReader reader = args.GetDataReader())
                {
                    uint dataAvailable;
                    while ((dataAvailable = reader.UnconsumedBufferLength) > 0)
                    {
                        ArraySegment <byte> buffer;
                        try
                        {
                            buffer = _receiveAsyncBufferTcs.Task.GetAwaiter().GetResult();
                        }
                        catch (OperationCanceledException) // Caused by Abort call on WebSocket
                        {
                            return;
                        }

                        _receiveAsyncBufferTcs = new TaskCompletionSource <ArraySegment <byte> >();
                        WebSocketMessageType messageType;
                        if (args.MessageType == SocketMessageType.Binary)
                        {
                            messageType = WebSocketMessageType.Binary;
                        }
                        else
                        {
                            messageType = WebSocketMessageType.Text;
                        }

                        bool endOfMessage = false;
                        uint readCount    = Math.Min(dataAvailable, (uint)buffer.Count);

                        if (readCount > 0)
                        {
                            IBuffer dataBuffer = reader.ReadBuffer(readCount);

                            // Safe to cast readCount to int as the maximum value that readCount can be is buffer.Count.
                            dataBuffer.CopyTo(0, buffer.Array, buffer.Offset, (int)readCount);
                        }

                        if (dataAvailable == readCount)
                        {
                            endOfMessage = !IsPartialMessageEvent(args);
                        }

                        WebSocketReceiveResult recvResult = new WebSocketReceiveResult((int)readCount, messageType,
                                                                                       endOfMessage);
                        _webSocketReceiveResultTcs.TrySetResult(recvResult);
                    }
                }
            }
            catch (Exception exc)
            {
                // WinRT WebSockets always throw exceptions of type System.Exception. However, we can determine whether
                // or not we're dealing with a known error by using WinRT's WebSocketError.GetStatus method.
                WebErrorStatus status      = RTWebSocketError.GetStatus(exc.HResult);
                WebSocketError actualError = WebSocketError.Faulted;
                switch (status)
                {
                case WebErrorStatus.ConnectionAborted:
                case WebErrorStatus.ConnectionReset:
                case WebErrorStatus.Disconnected:
                    actualError = WebSocketError.ConnectionClosedPrematurely;
                    break;
                }

                // Propagate a custom exception to any pending ReceiveAsync/CloseAsync operations and close the socket.
                WebSocketException customException = new WebSocketException(actualError, exc);
                AbortInternal(customException);
            }
        }
 static void CheckResultAndEnsureNotCloseMessage(WebSocketMessageSource messageSource, WebSocketReceiveResult result)
 {
     messageSource.CheckCloseStatus(result);
     if (result.MessageType == WebSocketMessageType.Close)
     {
         throw FxTrace.Exception.AsError(new ProtocolException(SR.WebSocketUnexpectedCloseMessageError));
     }
 }
            internal void CheckCloseStatus(WebSocketReceiveResult result)
            {
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    if (TD.WebSocketCloseStatusReceivedIsEnabled())
                    {
                        TD.WebSocketCloseStatusReceived(
                            _webSocket.GetHashCode(),
                            result.CloseStatus.ToString());
                    }

                    _closureReceived = true;
                    _closeDetails.InputCloseStatus = result.CloseStatus;
                    _closeDetails.InputCloseStatusDescription = result.CloseStatusDescription;
                }
            }
 public static string ReadString(this ArraySegment<byte> buffer, WebSocketReceiveResult result)
 {
     {
         return Encoding.UTF8.GetString(buffer.Array,
             buffer.Offset,
             result.Count);
     }
 }
示例#19
0
 public WebSocketReceiveResult(System.Net.WebSockets.WebSocketReceiveResult result)
 {
     mResult = result;
 }
示例#20
0
        private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationToken cancellationToken)
        {
            // The close message should be less than 125 bytes and fit in the buffer.
            await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, CancellationToken.None);

            // Status code and message are optional
            if (_frameBytesRemaining >= 2)
            {
                if (_unmaskInput)
                {
                    Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining));
                }
                _closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]);
                if (!ValidateCloseStatus(_closeStatus.Value))
                {
                    await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close status code.", cancellationToken);
                }
                try
                {
                    var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
                    _closeStatusDescription = encoding.GetString(_receiveBuffer, _receiveBufferOffset + 2, (int)_frameBytesRemaining - 2) ?? string.Empty;
                }
                catch (DecoderFallbackException)
                {
                    await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid UTF-8 close message.", cancellationToken);
                }
            }
            else if (_frameBytesRemaining == 1)
            {
                await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close body.", cancellationToken);
            }
            else
            {
                _closeStatus = _closeStatus ?? WebSocketCloseStatus.NormalClosure;
                _closeStatusDescription = _closeStatusDescription ?? string.Empty;
            }

            Contract.Assert(_frameInProgress.Fin);
            WebSocketReceiveResult result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, _frameInProgress.Fin,
                _closeStatus.Value, _closeStatusDescription);

            if (State == WebSocketState.Open)
            {
                _state = WebSocketState.CloseReceived;
            }
            else if (State == WebSocketState.CloseSent)
            {
                _state = WebSocketState.Closed;
                _stream.Dispose();
            }

            return result;
        }
示例#21
0
        private static async Task<WebSocketReceiveResult> GetWebSocket(WebSocket webSocket, ArraySegment<byte> buffer)
        {
            WebSocketReceiveResult result;

            try
            {
                result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
            }
            catch (Exception ex)
            {
                logger.LogVerbose("Exception in GetWebSocket: {0}", ex.Message);

                result = new WebSocketReceiveResult(buffer.Count, WebSocketMessageType.Text, false, WebSocketCloseStatus.ProtocolError, "ReceiveAsync error");
            }

            return result;
        }
        /// <summary>
        /// Receives data from the WebSocket connection asynchronously.
        /// </summary>
        /// <param name="buffer">
        /// References the application buffer that is the storage location for the received data.
        /// </param>
        /// <returns>
        /// A receive result representing a full message if we could receive one successfully
        /// within the specified buffer. null otherwise.
        /// </returns>
        /// <remarks>
        /// This method receives data from socket until either we get to the end of message sent
        /// by socket client or we fill the specified buffer. If we don't get to end of message
        /// within the allocated buffer space, we return a result value indicating that message
        /// is still incomplete.
        /// </remarks>
        protected async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer)
        {
            if (await this.CheckForDisconnectionAsync())
            {
                return null;
            }

            int receiveOffset = 0;
            int receiveCount = 0;
            bool isResponseComplete = false;
            WebSocketReceiveResult receiveResult = null;
                
            try
            {
                while (!isResponseComplete)
                {
                    if (receiveCount >= buffer.Count)
                    {
                        // If we've filled up the buffer and response message is still not
                        // complete, we won't have space for response at all, so just return
                        // incomplete message.
                        return new WebSocketReceiveResult(
                            receiveCount, receiveResult != null ? receiveResult.MessageType : WebSocketMessageType.Text, false);
                    }

                    receiveResult = await this.Socket.ReceiveAsync(new ArraySegment<byte>(buffer.Array, receiveOffset + buffer.Offset, buffer.Count - receiveOffset), this.CancellationTokenSource.Token);

                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        await this.SendCloseMessagesAsync(Properties.Resources.SocketClosedByClient, true);
                        return null;
                    }

                    receiveCount += receiveResult.Count;
                    receiveOffset += receiveResult.Count;
                    isResponseComplete = receiveResult.EndOfMessage;
                }

                receiveResult = new WebSocketReceiveResult(receiveCount, receiveResult.MessageType, true);
            }
            catch (Exception e)
            {
                if (!IsSendReceiveException(e))
                {
                    throw;
                }

                return null;
            }

            return receiveResult;
        }
示例#23
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);
            }
        }
示例#24
0
                protected override void ProcessAction_IndicateReceiveComplete(
                    Nullable<ArraySegment<byte>> buffer,
                    WebSocketProtocolComponent.BufferType bufferType,
                    WebSocketProtocolComponent.Action action,
                    Interop.WebSocket.Buffer[] dataBuffers,
                    uint dataBufferCount,
                    IntPtr actionContext)
                {
                    Debug.Assert(buffer != null, "'buffer MUST NOT be NULL.");

                    int bytesTransferred = 0;
                    _pongReceived = false;

                    if (bufferType == WebSocketProtocolComponent.BufferType.PingPong)
                    {
                        // ignoring received pong frame 
                        _pongReceived = true;
                        WebSocketProtocolComponent.WebSocketCompleteAction(_webSocket,
                            actionContext,
                            bytesTransferred);
                        return;
                    }

                    WebSocketReceiveResult receiveResult;
                    try
                    {
                        ArraySegment<byte> payload;
                        WebSocketMessageType messageType = GetMessageType(bufferType);
                        int newReceiveState = ReceiveState.Idle;

                        if (bufferType == WebSocketProtocolComponent.BufferType.Close)
                        {
                            payload = WebSocketValidate.EmptyPayload;
                            string reason;
                            WebSocketCloseStatus closeStatus;
                            _webSocket._internalBuffer.ConvertCloseBuffer(action, dataBuffers[0], out closeStatus, out reason);

                            receiveResult = new WebSocketReceiveResult(bytesTransferred,
                                messageType, true, closeStatus, reason);
                        }
                        else
                        {
                            payload = _webSocket._internalBuffer.ConvertNativeBuffer(action, dataBuffers[0], bufferType);

                            bool endOfMessage = bufferType ==
                                WebSocketProtocolComponent.BufferType.BinaryMessage ||
                                bufferType == WebSocketProtocolComponent.BufferType.UTF8Message ||
                                bufferType == WebSocketProtocolComponent.BufferType.Close;

                            if (payload.Count > buffer.Value.Count)
                            {
                                _webSocket._internalBuffer.BufferPayload(payload, buffer.Value.Count, messageType, endOfMessage);
                                newReceiveState = ReceiveState.PayloadAvailable;
                                endOfMessage = false;
                            }

                            bytesTransferred = Math.Min(payload.Count, (int)buffer.Value.Count);
                            if (bytesTransferred > 0)
                            {
                                Buffer.BlockCopy(payload.Array,
                                    payload.Offset,
                                    buffer.Value.Array,
                                    buffer.Value.Offset,
                                    bytesTransferred);
                            }

                            receiveResult = new WebSocketReceiveResult(bytesTransferred, messageType, endOfMessage);
                        }

                        _webSocket.UpdateReceiveState(newReceiveState, _receiveState);
                    }
                    finally
                    {
                        WebSocketProtocolComponent.WebSocketCompleteAction(_webSocket,
                            actionContext,
                            bytesTransferred);
                    }

                    ReceiveResult = receiveResult;
                }
示例#25
0
 private void OnCloseReceived(IWebSocket sender, WebSocketClosedEventArgs args)
 {
     var recvResult = new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, (WebSocketCloseStatus)args.Code,
         args.Reason);
     _closeWebSocketReceiveResultTcs.TrySetResult(recvResult);
 }
示例#26
0
 protected override void OnMessageReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     this.Send(context, "HELLO");
 }
示例#27
0
 protected override void OnFrameReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult)
 {
     throw new NotImplementedException();
 }
        internal void BufferPayload(ArraySegment<byte> payload, 
            int unconsumedDataOffset, 
            WebSocketMessageType messageType, 
            bool endOfMessage)
        {
            ThrowIfDisposed();
            int bytesBuffered = payload.Count - unconsumedDataOffset;

            Contract.Assert(m_PayloadOffset == 0,
                "'m_PayloadOffset' MUST be '0' at this point.");
            Contract.Assert(m_BufferedPayloadReceiveResult == null || m_BufferedPayloadReceiveResult.Count == 0,
                "'m_BufferedPayloadReceiveResult.Count' MUST be '0' at this point.");

            Buffer.BlockCopy(payload.Array,
                payload.Offset + unconsumedDataOffset,
                m_PayloadBuffer.Array,
                m_PayloadBuffer.Offset,
                bytesBuffered);

            m_BufferedPayloadReceiveResult =
                new WebSocketReceiveResult(bytesBuffered, messageType, endOfMessage);

            this.ValidateBufferedPayload();
        }
示例#29
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)
 {
     lock (SyncRoot)
     {
         var arg = System.Text.Encoding.UTF8.GetString(rxBuffer);
         Processes[context].StandardInput.WriteLine(arg);
     }
 }
示例#30
0
 public override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
 {
     Message input;
     while (true)
     {
         if (InputQueue.TryDequeue(out input))
             break;
         Thread.Sleep(500);
     }
     var serialized = Serializer.SerializeMessage(input);
     var i = 0;
     for(; i < buffer.Array.Length && i < serialized.Array.Length; i++)
     {
         buffer.Array[i] = serialized.Array[i];
     }
     var result = new WebSocketReceiveResult(i, WebSocketMessageType.Text, false);
     return Task.FromResult(result);
 }
 public Message Deserialize(WebSocketReceiveResult result, ArraySegment<byte> segment)
 {
     var json = Encoding.UTF8.GetString(segment.Array, 0, result.Count);
     return JsonConvert.DeserializeObject<Message>(json);
 }
        private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationToken cancellationToken)
        {
            // The close message should be less than 125 bytes and fit in the buffer.
            await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, CancellationToken.None);

            // Status code and message are optional
            if (_frameBytesRemaining >= 2)
            {
                if (_unmaskInput)
                {
                    Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining));
                }
                _closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]);
                _closeStatusDescription = Encoding.UTF8.GetString(_receiveBuffer, _receiveBufferOffset + 2, (int)_frameBytesRemaining - 2) ?? string.Empty;
            }
            else
            {
                _closeStatus = _closeStatus ?? WebSocketCloseStatus.NormalClosure;
                _closeStatusDescription = _closeStatusDescription ?? string.Empty;
            }

            Contract.Assert(_frameInProgress.Fin);
            WebSocketReceiveResult result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, _frameInProgress.Fin,
                _closeStatus.Value, _closeStatusDescription);

            if (State == WebSocketState.Open)
            {
                _state = WebSocketState.CloseReceived;
            }
            else if (State == WebSocketState.CloseSent)
            {
                _state = WebSocketState.Closed;
                _stream.Dispose();
            }

            return result;
        }
        internal bool ReceiveFromBufferedPayload(ArraySegment<byte> buffer, out WebSocketReceiveResult receiveResult)
        {
            ThrowIfDisposed();
            ValidateBufferedPayload();

            int bytesTransferred = Math.Min(buffer.Count, m_BufferedPayloadReceiveResult.Count);
            receiveResult = m_BufferedPayloadReceiveResult.Copy(bytesTransferred);

            Buffer.BlockCopy(m_PayloadBuffer.Array,
                m_PayloadBuffer.Offset + m_PayloadOffset,
                buffer.Array,
                buffer.Offset,
                bytesTransferred);

            bool morePayloadBuffered;
            if (m_BufferedPayloadReceiveResult.Count == 0)
            {
                m_PayloadOffset = 0;
                m_BufferedPayloadReceiveResult = null;
                morePayloadBuffered = false;
            }
            else
            {
                m_PayloadOffset += bytesTransferred;
                morePayloadBuffered = true;
                this.ValidateBufferedPayload();
            }

            return morePayloadBuffered;
        }
示例#34
0
 protected override void OnMessageReceived(WebSocketContext context, byte[] rxBuffer, WebSocketReceiveResult rxResult) {}
示例#35
0
        public override async Task<WebSocketReceiveResult> ReceiveAsync(
            ArraySegment<byte> buffer,
            CancellationToken cancellationToken)
        {
            _operation.InterlockedCheckValidStates(s_validReceiveStates);

            using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken))
            {
                // TODO (Issue 2505): replace with PinnableBufferCache.
                if (!_cachedReceivePinnedBuffer.IsAllocated || _cachedReceivePinnedBuffer.Target != buffer.Array)
                {
                    if (_cachedReceivePinnedBuffer.IsAllocated)
                    {
                        _cachedReceivePinnedBuffer.Free();
                    }

                    _cachedReceivePinnedBuffer = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
                }

                await InternalReceiveAsync(buffer).ConfigureAwait(false);

                // Check for abort.
                _operation.InterlockedCheckValidStates(s_validAfterReceiveStates);

                WebSocketMessageType bufferType;
                bool endOfMessage;
                bufferType = WebSocketMessageTypeAdapter.GetWebSocketMessageType(_operation.BufferType, out endOfMessage);

                int bytesTransferred = 0;
                checked
                {
                    bytesTransferred = (int)_operation.BytesTransferred;
                }

                WebSocketReceiveResult ret;

                if (bufferType == WebSocketMessageType.Close)
                {
                    UpdateServerCloseStatus();
                    ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage, _closeStatus, _closeStatusDescription);
                }
                else
                {
                    ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage);
                }

                return ret;
            }
        }
示例#36
0
        public override async Task<WebSocketReceiveResult> ReceiveAsync(
            ArraySegment<byte> buffer,
            CancellationToken cancellationToken)
        {
            _operation.InterlockedCheckValidStates(s_validReceiveStates);

            using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken))
            {
                _operation.PinReceiveBuffer(buffer);

                await InternalReceiveAsync(buffer).ConfigureAwait(false);

                // Check for abort.
                _operation.InterlockedCheckValidStates(s_validAfterReceiveStates);

                WebSocketMessageType bufferType;
                bool endOfMessage;
                bufferType = WebSocketMessageTypeAdapter.GetWebSocketMessageType(_operation.BufferType, out endOfMessage);

                int bytesTransferred = 0;
                checked
                {
                    bytesTransferred = (int)_operation.BytesTransferred;
                }

                WebSocketReceiveResult ret;

                if (bufferType == WebSocketMessageType.Close)
                {
                    UpdateServerCloseStatus();
                    ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage, _closeStatus, _closeStatusDescription);
                }
                else
                {
                    ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage);
                }

                return ret;
            }
        }