Class WebSocketFrameProxy

java.lang.Object
io.netty.channel.ChannelHandlerAdapter
io.netty.channel.ChannelInboundHandlerAdapter
io.netty.channel.SimpleChannelInboundHandler<io.netty.handler.codec.http.websocketx.WebSocketFrame>
org.openqa.selenium.netty.server.WebSocketFrameProxy
All Implemented Interfaces:
io.netty.channel.ChannelHandler, io.netty.channel.ChannelInboundHandler

public class WebSocketFrameProxy extends io.netty.channel.SimpleChannelInboundHandler<io.netty.handler.codec.http.websocketx.WebSocketFrame>
Installed in the client-side Netty pipeline by ProxyWebsocketsIntoGrid after the WebSocket upgrade handshake completes on both sides. It replaces the MessageInboundConverterWebSocketMessageHandler chain by forwarding WebSocketFrame objects directly to the node-side WebSocket, avoiding one intermediate Message allocation and one executor-task submission per frame.

The reverse direction (node → client) is handled by DirectForwardingListener inside ProxyWebsocketsIntoGrid, which writes TextWebSocketFrame/BinaryWebSocketFrame directly to the client Channel, bypassing MessageOutboundConverter.

Close frames are intentionally NOT handled here — they continue to flow through WebSocketUpgradeHandler which calls the registered Consumer<Message> with a CloseMessage and runs the Netty-level close handshake.

This handler is not @ChannelHandler.Sharable: each connection gets its own instance so that the fragmentation accumulators are per-connection.

  • Nested Class Summary

    Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler

    io.netty.channel.ChannelHandler.Sharable
  • Constructor Summary

    Constructors
    Constructor
    Description
    WebSocketFrameProxy(WebSocket upstream, AtomicBoolean upstreamClosing)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    channelRead0(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.http.websocketx.WebSocketFrame frame)
     
    static String
    Shrink a WebSocket close-frame reason to fit RFC 6455 §5.5.1's 123-byte UTF-8 cap.
    static void
    writeBinaryFrame(io.netty.channel.Channel clientChannel, byte[] data)
    Called by the node-side ForwardingListener to write a binary frame directly to the client channel, bypassing MessageOutboundConverter.
    static void
    writeTextFrame(io.netty.channel.Channel clientChannel, CharSequence text)
    Called by the node-side ForwardingListener to write a text frame directly to the client channel, bypassing MessageOutboundConverter.

    Methods inherited from class io.netty.channel.SimpleChannelInboundHandler

    acceptInboundMessage, channelRead

    Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter

    channelActive, channelInactive, channelReadComplete, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught, userEventTriggered

    Methods inherited from class io.netty.channel.ChannelHandlerAdapter

    ensureNotSharable, handlerAdded, handlerRemoved, isSharable

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface io.netty.channel.ChannelHandler

    handlerAdded, handlerRemoved
  • Constructor Details

  • Method Details

    • channelRead0

      protected void channelRead0(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.http.websocketx.WebSocketFrame frame)
      Specified by:
      channelRead0 in class io.netty.channel.SimpleChannelInboundHandler<io.netty.handler.codec.http.websocketx.WebSocketFrame>
    • writeTextFrame

      public static void writeTextFrame(io.netty.channel.Channel clientChannel, CharSequence text)
      Called by the node-side ForwardingListener to write a text frame directly to the client channel, bypassing MessageOutboundConverter.
    • writeBinaryFrame

      public static void writeBinaryFrame(io.netty.channel.Channel clientChannel, byte[] data)
      Called by the node-side ForwardingListener to write a binary frame directly to the client channel, bypassing MessageOutboundConverter.
    • truncateCloseReason

      public static String truncateCloseReason(String reason)
      Shrink a WebSocket close-frame reason to fit RFC 6455 §5.5.1's 123-byte UTF-8 cap.

      A naïve approach — encode to bytes, truncate, decode back — can split a multi-byte UTF-8 sequence at the boundary, which Java then decodes as U+FFFD (three bytes when re-encoded). That pushes the final encoded length back over the limit and breaks CloseWebSocketFrame encoding. Use CharsetEncoder into a 120-byte buffer instead — encode() stops at a clean character boundary on overflow, so no partial sequence is ever left behind. A three-byte ASCII ellipsis marks the truncation, keeping the encoded total at most 123 bytes regardless of the input.