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); }
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"); } }