Ejemplo n.º 1
0
        private void ReceiveThreadFunc(object param)
        {
            try
            {
                while (!closed)
                {
                    try
                    {
                        WebSocketFrameReader frame = new WebSocketFrameReader();
                        frame.Read(Stream);

                        // A server MUST NOT mask any frames that it sends to the client.  A client MUST close a connection if it detects a masked frame.
                        // In this case, it MAY use the status code 1002 (protocol error)
                        // (These rules might be relaxed in a future specification.)
                        if (frame.HasMask)
                        {
                            Close(1002, "Protocol Error: masked frame received from server!");
                            continue;
                        }

                        if (!frame.IsFinal)
                        {
                            if (OnIncompleteFrame == null)
                            {
                                IncompleteFrames.Add(frame);
                            }
                            else
                            {
                                lock (FrameLock) CompletedFrames.Add(frame);
                            }
                            continue;
                        }

                        switch (frame.Type)
                        {
                        // For a complete documentation and rules on fragmentation see http://tools.ietf.org/html/rfc6455#section-5.4
                        // A fragmented Frame's last fragment's opcode is 0 (Continuation) and the FIN bit is set to 1.
                        case WebSocketFrameTypes.Continuation:
                            // Do an assemble pass only if OnFragment is not set. Otherwise put it in the CompletedFrames, we will handle it in the HandleEvent phase.
                            if (OnIncompleteFrame == null)
                            {
                                frame.Assemble(IncompleteFrames);

                                // Remove all incomplete frames
                                IncompleteFrames.Clear();

                                // Control frames themselves MUST NOT be fragmented. So, its a normal text or binary frame. Go, handle it as usual.
                                goto case WebSocketFrameTypes.Binary;
                            }
                            else
                            {
                                lock (FrameLock) CompletedFrames.Add(frame);
                            }
                            break;

                        case WebSocketFrameTypes.Text:
                        case WebSocketFrameTypes.Binary:
                            frame.DecodeWithExtensions(WebSocket);
                            lock (FrameLock) CompletedFrames.Add(frame);
                            break;

                        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response, unless it already received a Close frame.
                        case WebSocketFrameTypes.Ping:
                            if (!closeSent && !closed)
                            {
                                Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Pong, frame.Data));
                            }
                            break;

                        // If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response.
                        case WebSocketFrameTypes.ConnectionClose:
                            CloseFrame = frame;
                            if (!closeSent)
                            {
                                Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.ConnectionClose, null));
                            }
                            closed = closeSent;
                            break;
                        }
                    }
#if !NETFX_CORE
                    catch (ThreadAbortException)
                    {
                        IncompleteFrames.Clear();
                        this.baseRequest.State = HTTPRequestStates.Aborted;

                        closed = true;
                    }
#endif
                    catch (Exception e)
                    {
                        if (HTTPUpdateDelegator.IsCreated)
                        {
                            this.baseRequest.Exception = e;
                            this.baseRequest.State     = HTTPRequestStates.Error;
                        }
                        else
                        {
                            this.baseRequest.State = HTTPRequestStates.Aborted;
                        }

                        closed = true;
                    }
                }
            }
            finally
            {
                HTTPManager.Heartbeats.Unsubscribe(this);
            }
        }
Ejemplo n.º 2
0
        private void ReceiveThreadFunc()
        {
            try
            {
                using (var bufferedStream = new ReadOnlyBufferedStream(this.Stream))
                {
                    while (!closed)
                    {
                        try
                        {
                            WebSocketFrameReader frame = new WebSocketFrameReader();
                            frame.Read(bufferedStream);

                            lastMessage = DateTime.UtcNow;

                            // A server MUST NOT mask any frames that it sends to the client.  A client MUST close a connection if it detects a masked frame.
                            // In this case, it MAY use the status code 1002 (protocol error)
                            // (These rules might be relaxed in a future specification.)
                            if (frame.HasMask)
                            {
                                Close(1002, "Protocol Error: masked frame received from server!");
                                continue;
                            }

                            if (!frame.IsFinal)
                            {
                                if (OnIncompleteFrame == null)
                                {
                                    IncompleteFrames.Add(frame);
                                }
                                else
                                {
                                    CompletedFrames.Enqueue(frame);
                                }
                                continue;
                            }

                            switch (frame.Type)
                            {
                            // For a complete documentation and rules on fragmentation see http://tools.ietf.org/html/rfc6455#section-5.4
                            // A fragmented Frame's last fragment's opcode is 0 (Continuation) and the FIN bit is set to 1.
                            case WebSocketFrameTypes.Continuation:
                                // Do an assemble pass only if OnFragment is not set. Otherwise put it in the CompletedFrames, we will handle it in the HandleEvent phase.
                                if (OnIncompleteFrame == null)
                                {
                                    frame.Assemble(IncompleteFrames);

                                    // Remove all incomplete frames
                                    IncompleteFrames.Clear();

                                    // Control frames themselves MUST NOT be fragmented. So, its a normal text or binary frame. Go, handle it as usual.
                                    goto case WebSocketFrameTypes.Binary;
                                }
                                else
                                {
                                    CompletedFrames.Enqueue(frame);
                                }
                                break;

                            case WebSocketFrameTypes.Text:
                            case WebSocketFrameTypes.Binary:
                                frame.DecodeWithExtensions(WebSocket);
                                CompletedFrames.Enqueue(frame);
                                break;

                            // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response, unless it already received a Close frame.
                            case WebSocketFrameTypes.Ping:
                                if (!closeSent && !closed)
                                {
                                    Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Pong, frame.Data));
                                }
                                break;

                            case WebSocketFrameTypes.Pong:
                                try
                                {
                                    // Get the ticks from the frame's payload
                                    long ticksSent = BitConverter.ToInt64(frame.Data, 0);

                                    // the difference between the current time and the time when the ping message is sent
                                    TimeSpan diff = TimeSpan.FromTicks(lastMessage.Ticks - ticksSent);

                                    // add it to the buffer
                                    this.rtts.Add((int)diff.TotalMilliseconds);

                                    // and calculate the new latency
                                    this.Latency = CalculateLatency();
                                }
                                catch
                                {
                                    // https://tools.ietf.org/html/rfc6455#section-5.5
                                    // A Pong frame MAY be sent unsolicited.  This serves as a
                                    // unidirectional heartbeat.  A response to an unsolicited Pong frame is
                                    // not expected.
                                }

                                break;

                            // If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response.
                            case WebSocketFrameTypes.ConnectionClose:
                                CloseFrame = frame;
                                if (!closeSent)
                                {
                                    Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.ConnectionClose, null));
                                }
                                closed = true;
                                break;
                            }
                        }
#if !NETFX_CORE
                        catch (ThreadAbortException)
                        {
                            IncompleteFrames.Clear();
                            this.baseRequest.State = HTTPRequestStates.Aborted;

                            closed = true;

                            newFrameSignal.Set();
                        }
#endif
                        catch (Exception e)
                        {
                            if (HTTPUpdateDelegator.IsCreated)
                            {
                                this.baseRequest.Exception = e;
                                this.baseRequest.State     = HTTPRequestStates.Error;
                            }
                            else
                            {
                                this.baseRequest.State = HTTPRequestStates.Aborted;
                            }

                            closed = true;
                            newFrameSignal.Set();
                        }
                    }
                }
            }
            finally
            {
                HTTPManager.Heartbeats.Unsubscribe(this);
                HTTPUpdateDelegator.OnApplicationForegroundStateChanged -= OnApplicationForegroundStateChanged;

                HTTPManager.Logger.Information("WebSocketResponse", "ReceiveThread - Closed!");
            }
        }
Ejemplo n.º 3
0
        private void ReceiveThreadFunc()
        {
            while (!this.closed)
            {
                try
                {
                    WebSocketFrameReader webSocketFrameReader = new WebSocketFrameReader();
                    webSocketFrameReader.Read(this.Stream);
                    if (webSocketFrameReader.HasMask)
                    {
                        this.Close(1002, "Protocol Error: masked frame received from server!");
                    }
                    else if (!webSocketFrameReader.IsFinal)
                    {
                        if (this.OnIncompleteFrame == null)
                        {
                            this.IncompleteFrames.Add(webSocketFrameReader);
                        }
                        else
                        {
                            object frameLock = this.FrameLock;
                            lock (frameLock)
                            {
                                this.CompletedFrames.Add(webSocketFrameReader);
                            }
                        }
                    }
                    else
                    {
                        switch (webSocketFrameReader.Type)
                        {
                        case WebSocketFrameTypes.Continuation:
                            if (this.OnIncompleteFrame != null)
                            {
                                object frameLock2 = this.FrameLock;
                                lock (frameLock2)
                                {
                                    this.CompletedFrames.Add(webSocketFrameReader);
                                }
                                continue;
                            }
                            webSocketFrameReader.Assemble(this.IncompleteFrames);
                            this.IncompleteFrames.Clear();
                            break;

                        case WebSocketFrameTypes.Text:
                        case WebSocketFrameTypes.Binary:
                            break;

                        case (WebSocketFrameTypes)3:
                        case (WebSocketFrameTypes)4:
                        case (WebSocketFrameTypes)5:
                        case (WebSocketFrameTypes)6:
                        case (WebSocketFrameTypes)7:
                            continue;

                        case WebSocketFrameTypes.ConnectionClose:
                            this.CloseFrame = webSocketFrameReader;
                            if (!this.closeSent)
                            {
                                this.Send(new WebSocketClose());
                            }
                            this.closed = this.closeSent;
                            continue;

                        case WebSocketFrameTypes.Ping:
                            if (!this.closeSent && !this.closed)
                            {
                                this.Send(new WebSocketPong(webSocketFrameReader));
                            }
                            continue;

                        default:
                            continue;
                        }
                        if (this.OnText != null)
                        {
                            object frameLock3 = this.FrameLock;
                            lock (frameLock3)
                            {
                                this.CompletedFrames.Add(webSocketFrameReader);
                            }
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    this.IncompleteFrames.Clear();
                    this.closed = true;
                }
                catch (Exception exception)
                {
                    this.baseRequest.Exception = exception;
                    this.closed = true;
                }
            }
            HTTPManager.Heartbeats.Unsubscribe(this);
        }
Ejemplo n.º 4
0
        private void ReceiveThreadFunc()
        {
            while (!closed)
            {
                try
                {
                    WebSocketFrameReader frame = new WebSocketFrameReader();
                    frame.Read(Stream);

                    // A server MUST NOT mask any frames that it sends to the client.  A client MUST close a connection if it detects a masked frame.
                    // In this case, it MAY use the status code 1002 (protocol error)
                    // (These rules might be relaxed in a future specification.)
                    if (frame.HasMask)
                    {
                        Close(1002, "Protocol Error: masked frame received from server!");
                        continue;
                    }

                    if (!frame.IsFinal)
                    {
                        if (OnIncompleteFrame == null)
                        {
                            IncompleteFrames.Add(frame);
                        }
                        else
                        {
                            lock (FrameLock) CompletedFrames.Add(frame);
                        }
                        continue;
                    }

                    switch (frame.Type)
                    {
                    // For a complete documentation and rules on fragmentation see http://tools.ietf.org/html/rfc6455#section-5.4
                    // A fragmented Frame's last fragment's opcode is 0 (Continuation) and the FIN bit is set to 1.
                    case WebSocketFrameTypes.Continuation:
                        // Do an assemble pass only if OnFragment is not set. Otherwise put it in the CompletedFrames, we will handle it in the HandleEvent phase.
                        if (OnIncompleteFrame == null)
                        {
                            frame.Assemble(IncompleteFrames);

                            // Remove all imcomplete frames
                            IncompleteFrames.Clear();

                            // Control frames themselves MUST NOT be fragmented. So, its a normal text or binary frame. Go, handle it as usual.
                            goto case WebSocketFrameTypes.Binary;
                        }
                        else
                        {
                            lock (FrameLock) CompletedFrames.Add(frame);
                        }
                        break;

                    case WebSocketFrameTypes.Text:
                    case WebSocketFrameTypes.Binary:
                        if (OnText != null)
                        {
                            lock (FrameLock) CompletedFrames.Add(frame);
                        }
                        break;

                    // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response, unless it already received a Close frame.
                    case WebSocketFrameTypes.Ping:
                        if (!closeSent && !closed)
                        {
                            Send(new WebSocketPong(frame));
                        }
                        break;

                    // If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response.
                    case WebSocketFrameTypes.ConnectionClose:
                        CloseFrame = frame;
                        if (!closeSent)
                        {
                            Send(new WebSocketClose());
                        }
                        closed = closeSent;
                        break;
                    }
                }
                catch (ThreadAbortException)
                {
                    IncompleteFrames.Clear();

                    closed = true;
                }
                catch (Exception e)
                {
                    this.baseRequest.Exception = e;
                    closed = true;
                }
            }

            Interlocked.Increment(ref ClosedCount);

            if (PingThread != null)
            {
                // closed is true and the Ping thread should be exit, but if something went very bad we must Abort() the thread
                if (PingThread.Join(1000))
                {
                    PingThread.Abort();
                }
            }
        }
        private void ReceiveThreadFunc()
        {
            while (!closed)
            {
                try
                {
                    WebSocketFrameReader webSocketFrameReader = new WebSocketFrameReader();
                    webSocketFrameReader.Read(Stream);
                    if (webSocketFrameReader.HasMask)
                    {
                        Close(1002, "Protocol Error: masked frame received from server!");
                    }
                    else if (webSocketFrameReader.IsFinal)
                    {
                        switch (webSocketFrameReader.Type)
                        {
                        case (WebSocketFrameTypes)3:
                        case (WebSocketFrameTypes)4:
                        case (WebSocketFrameTypes)5:
                        case (WebSocketFrameTypes)6:
                        case (WebSocketFrameTypes)7:
                            break;

                        case WebSocketFrameTypes.Continuation:
                            if (OnIncompleteFrame != null)
                            {
                                lock (FrameLock)
                                {
                                    CompletedFrames.Add(webSocketFrameReader);
                                }
                                break;
                            }
                            webSocketFrameReader.Assemble(IncompleteFrames);
                            IncompleteFrames.Clear();
                            goto case WebSocketFrameTypes.Text;

                        case WebSocketFrameTypes.Text:
                        case WebSocketFrameTypes.Binary:
                            if (OnText != null)
                            {
                                lock (FrameLock)
                                {
                                    CompletedFrames.Add(webSocketFrameReader);
                                }
                            }
                            break;

                        case WebSocketFrameTypes.Ping:
                            if (!closeSent && !closed)
                            {
                                Send(new WebSocketPong(webSocketFrameReader));
                            }
                            break;

                        case WebSocketFrameTypes.Pong:
                            if (OnPong != null)
                            {
                                lock (FrameLock)
                                {
                                    CompletedFrames.Add(webSocketFrameReader);
                                }
                            }
                            break;

                        case WebSocketFrameTypes.ConnectionClose:
                            CloseFrame = webSocketFrameReader;
                            if (!closeSent)
                            {
                                Send(new WebSocketClose());
                            }
                            closed = closeSent;
                            break;
                        }
                    }
                    else if (OnIncompleteFrame == null)
                    {
                        IncompleteFrames.Add(webSocketFrameReader);
                    }
                    else
                    {
                        lock (FrameLock)
                        {
                            CompletedFrames.Add(webSocketFrameReader);
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    IncompleteFrames.Clear();
                    closed = true;
                }
                catch (Exception exception)
                {
                    baseRequest.Exception = exception;
                    closed = true;
                }
            }
            Interlocked.Increment(ref ClosedCount);
            if (PingThread != null && PingThread.Join(1000))
            {
                PingThread.Abort();
            }
        }
Ejemplo n.º 6
0
        private void ReceiveThreadFunc(object param)
        {
            try
            {
                while (!closed)
                {
                    try
                    {
                        WebSocketFrameReader webSocketFrameReader = new WebSocketFrameReader();
                        webSocketFrameReader.Read(Stream);
                        if (webSocketFrameReader.HasMask)
                        {
                            Close(1002, "Protocol Error: masked frame received from server!");
                        }
                        else if (webSocketFrameReader.IsFinal)
                        {
                            switch (webSocketFrameReader.Type)
                            {
                            case (WebSocketFrameTypes)3:
                            case (WebSocketFrameTypes)4:
                            case (WebSocketFrameTypes)5:
                            case (WebSocketFrameTypes)6:
                            case (WebSocketFrameTypes)7:
                                break;

                            case WebSocketFrameTypes.Continuation:
                                if (OnIncompleteFrame != null)
                                {
                                    lock (FrameLock)
                                    {
                                        CompletedFrames.Add(webSocketFrameReader);
                                    }
                                    break;
                                }
                                webSocketFrameReader.Assemble(IncompleteFrames);
                                IncompleteFrames.Clear();
                                goto case WebSocketFrameTypes.Text;

                            case WebSocketFrameTypes.Text:
                            case WebSocketFrameTypes.Binary:
                                lock (FrameLock)
                                {
                                    CompletedFrames.Add(webSocketFrameReader);
                                }
                                break;

                            case WebSocketFrameTypes.Ping:
                                if (!closeSent && !closed)
                                {
                                    Send(new WebSocketPong(webSocketFrameReader));
                                }
                                break;

                            case WebSocketFrameTypes.ConnectionClose:
                                CloseFrame = webSocketFrameReader;
                                if (!closeSent)
                                {
                                    Send(new WebSocketClose());
                                }
                                closed = closeSent;
                                break;
                            }
                        }
                        else if (OnIncompleteFrame == null)
                        {
                            IncompleteFrames.Add(webSocketFrameReader);
                        }
                        else
                        {
                            lock (FrameLock)
                            {
                                CompletedFrames.Add(webSocketFrameReader);
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        IncompleteFrames.Clear();
                        baseRequest.State = HTTPRequestStates.Aborted;
                        closed            = true;
                    }
                    catch (Exception exception)
                    {
                        if (HTTPUpdateDelegator.IsCreated)
                        {
                            baseRequest.Exception = exception;
                            baseRequest.State     = HTTPRequestStates.Error;
                        }
                        else
                        {
                            baseRequest.State = HTTPRequestStates.Aborted;
                        }
                        closed = true;
                    }
                }
            }
            finally
            {
                HTTPManager.Heartbeats.Unsubscribe(this);
            }
        }