Question

I have a websocket server using Netty (4.0.17) that answers requests from a JavaScript client. The communication works fine but I have an exception when I try to immediately send a greeting message when a client connects.

My code looks like that :

public class LiveOthelloWSHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ChannelFuture f = ctx.channel().writeAndFlush(new TextWebSocketFrame("(gameID=0)[LiveOthelloServer="+ VERSION_NUMBER + "]\n"));
    }

// ...

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {

        final String request = frame.text();
        Channel thisChannel = ctx.channel();

        // Do something with request
        // Write back

        thisChannel.writeAndFlush(new TextWebSocketFrame(response + "\n"));
    }
}

The channelRead0() is ok, the client sends messages and the server answers back without any issue. What doesn't work is the "greetings" part. I would like to send a welcoming message to the client (the string using VERSION_NUMBER in the ChannelActive() method) but I always get an exception :

java.lang.UnsupportedOperationException: unsupported message type: TextWebSocketFrame

I guess this is maybe because the channelActive() gets invoked as soon as the connection is established but before the websocket handshake is complete. How can I wait for the handshake to be finished and then send the greeting message (without the client having sent any request yet)?

For information, my initialization is:

@Override
public void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    pipeline.addLast(
                     new HttpRequestDecoder(),
                     new HttpObjectAggregator(65536),
                     new HttpResponseEncoder(),
                     new WebSocketServerProtocolHandler("/websocket"),
                     myLiveOthelloWSHandler);
Was it helpful?

Solution

Just RTFM...

http://netty.io/4.0/api/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.html

Best way to detect handshake is to override ChannelInboundHandler.userEventTriggered... So I just had to add:

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    super.userEventTriggered(ctx, evt);
    if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
        ChannelFuture f = ctx.channel().writeAndFlush(new TextWebSocketFrame("(gameID=0)[LiveOthelloServer="+ VERSION_NUMBER + "]\n"));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top