-3

我将编写聊天室使用 netty 作为服务器。并为客户闪存。该协议使用带有“\r\n”结尾的json字符串。我编写了三个处理程序“MessageDecoder”、“MessageHandler”、“MessageEncoder”。并使用 flash 客户端发送消息。但我得到以下错误。

 java.lang.IllegalStateException: decode() method must read at least one byte if it returned a frame (caused by: class com.mbaobao.chatroom.socket.handlers.MessageDecoder)
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:294)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:351)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:282)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:202)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)

消息解码器

    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
                                                                                            throws Exception {
    logger.debug("message decode");
    if (buffer.readableBytes() < 4) {
        return null;
    }

    StringBuffer stringBuffer = new StringBuffer();
    String json = null;
    for (int i = 0; i < buffer.capacity(); i++) {
        char c = (char) buffer.getByte(i);
        logger.info(c);
        stringBuffer.append(c);
        if (c == 13 || c == 10) {
            json = stringBuffer.toString();
            break;
        }
    }
    ChatData chatData = JSON.parseObject(json, ChatData.class);

    return chatData;

}

我从不写套接字程序。只知道使用 mutil 线程管理套接字。但我认为这很可怕。所以我使用 netty 。但我不知道如何将它用于聊天室。

有人可以给我推荐吗?

4

3 回答 3

1

确保将接收到的 ChannelBuffer 的阅读器索引定位到您刚刚阅读的消息结束的位置。@see ChannelBuffer.readerIndex(int) 这是因为 ChannelBuffer.getByte(int) / .getBytes() 不会改变阅读器索引。

如果你不这样做,Netty 将假定你没有从缓冲区中读取任何字节(如果有的话,将它交给管道中的下一个处理程序)并抛出你刚刚遇到的异常。

于 2012-04-01T14:08:01.303 回答
1

只需将 buffer.getByte(..) 替换为 buffer.readByte() 即可解决此问题。

于 2012-04-01T16:17:45.413 回答
0

我建议您使用内置功能来处理 Netty API 中提供的字符串。

  • DelimiterBasedFrameDecoder
  • StringDecoder
  • StringEncoder

我尝试创建指向相应文档页面的链接,但 stackoverflow 阻止我发布两个以上的链接。

Netty SecureChat 示例非常清楚地解释了如何在您的通道管道上使用这些处理程序。

于 2012-04-01T15:58:49.763 回答