예제 #1
0
        protected void smWaitCloseResponse()
        {
            int bytesRead = 0;

            this.posHeaderEOF  = 0;
            this.bytesInBuffer = 0;

            if (this.socket.Poll(this.waitCloseMsgTimeout, SelectMode.SelectRead) == true && this.socket.Available > 0)
            {
                do
                {
                    bytesRead = this.socketStream.Read(this.receiveBuffer, this.bytesInBuffer, this.receiveBuffer.Length - this.bytesInBuffer);
                    if (bytesRead > 0)
                    {
                        this.bytesInBuffer += bytesRead;
                        if (WSFrame.TryParse(this.receiveBuffer, 0, this.bytesInBuffer, this.options.MaxReceiveFrameLength, out this.lastRcvdFrame) == true)
                        {
                            // remove data-frame from buffer
                            Array.Copy(this.receiveBuffer, this.lastRcvdFrame.FrameData.Length, this.receiveBuffer, 0, this.bytesInBuffer - this.lastRcvdFrame.FrameData.Length);
                            this.bytesInBuffer = this.bytesInBuffer - this.lastRcvdFrame.FrameData.Length;

                            // check for close frame
                            if (this.lastRcvdFrame.OpCode == WSFrameType.Close)
                            {
                                this.LogBufferContent("Close frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                                this.subState = SubState.CloseTcpConnection;
                                return;
                            }

                            this.LogBufferContent("Data frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                        }
                    }
                }while (this.socket.Available > 0 && this.bytesInBuffer < this.receiveBuffer.Length);
            }

            Logger.WriteError(this.loggerID, "Close frame not received.");
            this.subState = SubState.Failed;
        }
예제 #2
0
        protected void smReceive()
        {
            int bytesRead = 0;

            this.lastRcvdFrame = null;

            // start activity timer
            if (this.activityTimerEnabled)
            {
                this.activityTimer.Start(this.waitActivityTimeout, ActivityTimerState.WaitingForMessage);
            }

            while (this.State == WebSocketState.Connected)
            {
                // process data in buffer
                if (this.bytesInBuffer > 0)
                {
                    if (WSFrame.TryParse(this.receiveBuffer, 0, this.bytesInBuffer, this.options.MaxReceiveFrameLength, out this.lastRcvdFrame) == true)
                    {
                        // restart activity timer
                        if (this.activityTimerEnabled)
                        {
                            this.activityTimer.Restart(ActivityTimerState.WaitingForMessage);
                        }

                        // remove data-frame from buffer
                        Array.Copy(this.receiveBuffer, this.lastRcvdFrame.FrameData.Length, this.receiveBuffer, 0, this.bytesInBuffer - this.lastRcvdFrame.FrameData.Length);
                        this.bytesInBuffer = this.bytesInBuffer - this.lastRcvdFrame.FrameData.Length;

                        // take action based on opcode
                        switch (this.lastRcvdFrame.OpCode)
                        {
                        case WSFrameType.Continuation:
                            // TODO - implement continuation frames
                            break;

                        case WSFrameType.Text:
                            this.LogBufferContent("Text frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            this.OnTextReceived(this.lastRcvdFrame.PayloadText);
                            break;

                        case WSFrameType.Binary:
                            this.LogBufferContent("Data frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            this.OnDataReceived(this.lastRcvdFrame.PayloadBytes);
                            break;

                        case WSFrameType.Close:
                            this.LogBufferContent("Close frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            // based on RFC6455 we must stop sending and receiving messages after Close response is sent
                            this.activityTimer.Stop();
                            this.state    = WebSocketState.Disconnecting;
                            this.subState = SubState.CloseTcpConnection;
                            this.smSendCloseResponse();
                            return;

                        case WSFrameType.Ping:
                            this.LogBufferContent("Ping frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            this.smSendPongMessage();
                            break;

                        case WSFrameType.Pong:
                            this.LogBufferContent("Pong frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            // no need to do anything
                            break;

                        default:
                            this.LogBufferContent("Unknown frame received: ", this.lastRcvdFrame.FrameData, 0, this.lastRcvdFrame.FrameData.Length);
                            break;
                        }
                    }
                }

                // send queued messages
                if (this.DequeueAndSendMessages() && this.activityTimerEnabled)
                {
                    this.activityTimer.Restart(ActivityTimerState.MessageSent);
                }

                // get more data
                if (this.socket.Poll(this.waitReceiveTimeout, SelectMode.SelectRead) == true && this.socket.Available > 0)
                {
                    bytesRead           = this.socketStream.Read(this.receiveBuffer, this.bytesInBuffer, this.receiveBuffer.Length - this.bytesInBuffer);
                    this.bytesInBuffer += bytesRead;
                    continue;
                }

                // check activity timer
                if (this.activityTimer.HasTimedOut)
                {
                    switch ((ActivityTimerState)this.activityTimer.State)
                    {
                    case ActivityTimerState.MessageSent:
                    case ActivityTimerState.WaitingForMessage:
                        this.smSendPingMessage();
                        activityTimer.Restart(ActivityTimerState.WaitingForPingResponse);
                        break;

                    case ActivityTimerState.WaitingForPingResponse:
                        Logger.WriteError(this.loggerID, string.Concat("Ping response timed out."));
                        activityTimer.Stop();
                        this.state    = WebSocketState.Disconnecting;
                        this.subState = SubState.CloseTcpConnection;
                        break;
                    }
                }
            }
        }