websocketstaticnettybytebufferjava-websocket

can TextWebSocketFrame be declared with static and final?


In Netty, send messages are like this:

channel.writeAndFlush(new TextWebSocketFrame("Operation Succeed"));

to run this code, nothing abnormal. so I think, argument from writeAndFlush can be extracted to a static and final variable like this:

public class LogicHandler extends SimpleUserEventChannelHandler<WebSocketServerProtocolHandler.HandshakeComplete> {
    static final TextWebSocketFrame SUCCEED = new TextWebSocketFrame("Operation Succeed");

    @Override
    protected void eventReceived(ChannelHandlerContext context, WebSocketServerProtocolHandler.HandshakeComplete arg) {
        context.channel().writeAndFlush(SUCCEED.retain()); // the client received empty content
    } 
}

to run this codes, abnormal things happen:

the client(WebSocket from Chrome browser) received the message but empty content



Are there any ideas that i can do with it?

remove the method "retain" can not solve the problem, the only way is to remove static and final keyword.


Solution

  • Because the underlying ByteBuf's readerIndex is updated once used. You can reuse it by reset the readerIndex, like below. But this code is thread-unsafe, it can cause problems when there are multiple connections.

    public static class LogicHandler extends SimpleUserEventChannelHandler<WebSocketServerProtocolHandler.HandshakeComplete> {
        static final TextWebSocketFrame SUCCEED = new TextWebSocketFrame("Operation Succeed");
    
        @Override
        protected void eventReceived(ChannelHandlerContext context, WebSocketServerProtocolHandler.HandshakeComplete arg) {
            SUCCEED.content().readerIndex(0);
            context.channel().writeAndFlush(SUCCEED.retain());
        }
    }
    

    This is thread-safe

    public static class LogicHandler extends SimpleUserEventChannelHandler<WebSocketServerProtocolHandler.HandshakeComplete> {
        static final TextWebSocketFrame SUCCEED = new TextWebSocketFrame("Operation Succeed");
    
        @Override
        protected void eventReceived(ChannelHandlerContext context, WebSocketServerProtocolHandler.HandshakeComplete arg) {
            context.channel().writeAndFlush(SUCCEED.retainedDuplicate());
        }
    }