예제 #1
0
        /// <summary>
        /// Processes the packet within the context. Returns true whether the packet was processed or throttled.
        /// </summary>
        /// <param name="channel">The through which the packet is coming/going out.</param>
        /// <param name="context">The packet context for this operation.</param>
        /// <returns>True whether the packet was processed or throttled, false otherwise.</returns>
        public static ProcessingState Process(Emitter.Connection channel, ProcessingContext context)
        {
            // Get the buffer
            var buffer = context.Buffer;

            if (buffer == null)
            {
                return(ProcessingState.Failure);
            }

            // Get the info
            var pBuffer = buffer.AsBytePointer();
            int length  = buffer.Length;

            // To close the connection cleanly, a frame consisting of just a 0xFF
            // byte followed by a 0x00 byte is sent from one peer to ask that the
            // other peer close the connection.
            if (*pBuffer == 0xFF && *(pBuffer + 1) == 0x00)
            {
                // Trace a websocket event
                NetTrace.WriteLine("Draft76 connection termination requested", channel, NetTraceCategory.WebSocket);

                length = 0;
                channel.Close();
                return(ProcessingState.Stop);
            }

            if (*pBuffer != Start)
            {
                throw new WebSocketException("WebSocket frame is invalid.");
            }

            // Search for the next end byte
            int endIndex = -1;

            for (int i = 0; i < length; ++i)
            {
                if (*(pBuffer + i) == End)
                {
                    endIndex = i;
                    break;
                }
            }

            if (endIndex == -1)
            {
                // Trace a websocket event
                NetTrace.WriteLine("Draft76 frame is not complete", channel, NetTraceCategory.WebSocket);
                return(ProcessingState.InsufficientData);
            }

            if (endIndex > MaxSize)
            {
                throw new WebSocketException("WebSocket frame is too large.");
            }

            // Throttle the rest
            context.Throttle(endIndex + 1);

            // Decode the body
            var decoded = context.BufferWrite(buffer.Array, buffer.Offset + 1, endIndex - 1);

            context.SwitchBuffer(decoded);

            // Trace a websocket event
            NetTrace.WriteLine("Draft76 frame decoded", channel, NetTraceCategory.WebSocket);
            return(ProcessingState.Success);
        }