protected internal override void Encode(IChannelHandlerContext ctx, WebSocketFrame msg, List <object> output)
        {
            if (this.encoder == null)
            {
                this.encoder = new EmbeddedChannel(
                    ZlibCodecFactory.NewZlibEncoder(
                        ZlibWrapper.None,
                        this.compressionLevel,
                        this.windowSize,
                        8));
            }

            this.encoder.WriteOutbound(msg.Content.Retain());

            CompositeByteBuffer fullCompressedContent = ctx.Allocator.CompositeBuffer();

            for (;;)
            {
                var partCompressedContent = this.encoder.ReadOutbound <IByteBuffer>();
                if (partCompressedContent == null)
                {
                    break;
                }

                if (!partCompressedContent.IsReadable())
                {
                    partCompressedContent.Release();
                    continue;
                }

                fullCompressedContent.AddComponent(true, partCompressedContent);
            }

            if (fullCompressedContent.NumComponents <= 0)
            {
                fullCompressedContent.Release();
                throw new CodecException("cannot read compressed buffer");
            }

            if (msg.IsFinalFragment && this.noContext)
            {
                this.Cleanup();
            }

            IByteBuffer compressedContent;

            if (this.RemoveFrameTail(msg))
            {
                int realLength = fullCompressedContent.ReadableBytes - FrameTail.Length;
                compressedContent = fullCompressedContent.Slice(0, realLength);
            }
            else
            {
                compressedContent = fullCompressedContent;
            }

            WebSocketFrame outMsg;

            if (msg is TextWebSocketFrame)
            {
                outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent);
            }
            else if (msg is BinaryWebSocketFrame)
            {
                outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent);
            }
            else if (msg is ContinuationWebSocketFrame)
            {
                outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent);
            }
            else
            {
                throw new CodecException($"unexpected frame type: {msg.GetType().Name}");
            }

            output.Add(outMsg);
        }
Exemple #2
0
        protected internal override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, List <object> output)
        {
            if (this.decoder == null)
            {
                if (!(msg is TextWebSocketFrame) && !(msg is BinaryWebSocketFrame))
                {
                    throw new CodecException($"unexpected initial frame type: {msg.GetType().Name}");
                }

                this.decoder = new EmbeddedChannel(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));
            }

            bool readable = msg.Content.IsReadable();

            this.decoder.WriteInbound(msg.Content.Retain());
            if (this.AppendFrameTail(msg))
            {
                this.decoder.WriteInbound(Unpooled.WrappedBuffer(FrameTail));
            }

            CompositeByteBuffer compositeUncompressedContent = ctx.Allocator.CompositeDirectBuffer();

            for (;;)
            {
                var partUncompressedContent = this.decoder.ReadInbound <IByteBuffer>();
                if (partUncompressedContent == null)
                {
                    break;
                }

                if (!partUncompressedContent.IsReadable())
                {
                    partUncompressedContent.Release();
                    continue;
                }

                compositeUncompressedContent.AddComponent(true, partUncompressedContent);
            }

            // Correctly handle empty frames
            // See https://github.com/netty/netty/issues/4348
            if (readable && compositeUncompressedContent.NumComponents <= 0)
            {
                compositeUncompressedContent.Release();
                throw new CodecException("cannot read uncompressed buffer");
            }

            if (msg.IsFinalFragment && this.noContext)
            {
                this.Cleanup();
            }

            WebSocketFrame outMsg;

            if (msg is TextWebSocketFrame)
            {
                outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else if (msg is BinaryWebSocketFrame)
            {
                outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else if (msg is ContinuationWebSocketFrame)
            {
                outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else
            {
                throw new CodecException($"unexpected frame type: {msg.GetType().Name}");
            }

            output.Add(outMsg);
        }
        private void onWebSocketMessageReceived(WebSocketFrame frame)
        {
            if (frame.GetType() != typeof(WebSocketBinaryFrame))
            {
                CloseSocket();
                return;
            }
            WebSocketBinaryFrame bf = frame as WebSocketBinaryFrame;

            byte[] buf = bf.Data;

            Console.WriteLine(ID + " OnMessage(" + buf.Length + ")");
            if (buf.Length == 0)
            {
                CloseSocket();
                return;
            }

            Command cmd = (Command)buf[0];

            Console.WriteLine(ID + " OnMessage: " + cmd);
            try
            {
                switch (cmd)
                {
                case Command.StartStreaming:
                    if (buf.Length < 3)
                    {
                        SyntaxError(buf[0], buf);
                        break;
                    }
                    StopStreaming();
                    Console.WriteLine(ID + " Command.StartStreaming " + (byte)Interlocked.Read(ref activeStreamNumber));
                    socket.Send(new byte[] { buf[0], (byte)Interlocked.Read(ref activeStreamNumber) });
                    StartStreaming(buf);
                    break;

                case Command.StopStreaming:
                    Console.WriteLine(ID + " Command.StopStreaming");
                    StopStreaming();
                    break;

                case Command.AcknowledgeFrame:
                    if (buf.Length < 2)
                    {
                        SyntaxError(buf[0], buf);
                        break;
                    }
                    AcknowledgeFrame(buf[1]);
                    break;

                case Command.ReproduceUserInput:
                    if (buf.Length < 2)
                    {
                        SyntaxError(buf[0], buf);
                        break;
                    }
                    InputType inputType = (InputType)buf[1];
                    if (inputType == InputType.KeyDown || inputType == InputType.KeyUp)
                    {
                        if (buf.Length < 10)
                        {
                            SyntaxError(buf[0], buf, inputType);
                            break;
                        }
                        int          keyCode   = ByteUtil.ReadInt32(buf, 2);
                        ModifierKeys modifiers = (ModifierKeys)ByteUtil.ReadUInt32(buf, 6);
                        streamerController.DoKeyboardInput(keyCode, modifiers, inputType == InputType.KeyUp);
                    }
                    else if (inputType == InputType.MouseMove)
                    {
                        if (buf.Length < 10)
                        {
                            SyntaxError(buf[0], buf, inputType);
                            break;
                        }
                        float x = ByteUtil.ReadFloat(buf, 2);
                        float y = ByteUtil.ReadFloat(buf, 6);
                        streamerController.DoMouseMove(x, y);
                    }
                    else if (inputType == InputType.MouseButtonDown || inputType == InputType.MouseButtonUp)
                    {
                        if (buf.Length < 3)
                        {
                            SyntaxError(buf[0], buf, inputType);
                            break;
                        }
                        MouseButton button = (MouseButton)buf[2];
                        streamerController.DoMouseButton(button, inputType == InputType.MouseButtonUp);
                    }
                    else if (inputType == InputType.MouseWheel)
                    {
                        if (buf.Length < 6)
                        {
                            SyntaxError(buf[0], buf, inputType);
                            break;
                        }
                        short deltaX = ByteUtil.ReadInt16(buf, 2);
                        short deltaY = ByteUtil.ReadInt16(buf, 4);
                        streamerController.DoMouseWheel(deltaX, deltaY);
                    }
                    break;

                case Command.GetDesktopInfo:
                    DesktopInfo desktopInfo = streamerController.GetDesktopInfo();
                    using (MemoryDataStream mds = new MemoryDataStream())
                    {
                        desktopInfo.WriteToDataStream(mds);
                        socket.Send(mds.ToArray());
                    }
                    break;

                case Command.SetStreamSettings:
                    if (buf.Length < 5)
                    {
                        SyntaxError(buf[0], buf);
                        break;
                    }

                    imgFlags                = (ImgFlags)buf[1];
                    jpegQuality             = BPMath.Clamp <byte>(buf[2], 1, 100);
                    maxFPS                  = BPMath.Clamp <byte>(buf[3], 1, byte.MaxValue);
                    maxUnacknowledgedFrames = BPMath.Clamp <byte>(buf[4], 1, byte.MaxValue);
                    break;

                case Command.GetStreamSettings:
                    byte[] response = new byte[4];
                    response[0] = buf[0];
                    response[1] = (byte)imgFlags;
                    response[2] = jpegQuality;
                    response[3] = maxFPS;
                    socket.Send(response);
                    break;

                case Command.KeepAlive:
                    break;

                default:
                    // CloseSocket();
                    socket.Send(new byte[] { (byte)Command.Error_CommandCodeUnknown });
                    break;
                }
            }
            catch (ThreadAbortException) { throw; }
            catch (Exception ex)
            {
                Logger.Debug(ex, "WebSocketServer");
            }
        }