Netty channelRead 从未调用过
Posted
技术标签:
【中文标题】Netty channelRead 从未调用过【英文标题】:Netty channelRead never called 【发布时间】:2014-02-15 13:24:19 【问题描述】:我玩过 netty 并跟着视频 (https://www.youtube.com/watch?v=tsz-assb1X8) 构建了一个聊天服务器和客户端,服务器正常工作(我用 telnet 测试过,这里可以正常工作)但客户端不接收数据。 ChatClinetHandler.java 中的 channelRead 方法从未被调用,但 channelReadComplete 被调用。
ChatClient.java
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NiosocketChannel;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ChatClient
public static void main(String args[])
try
new ChatClient(new InetSocketAddress("localhost", 8000)).run();
catch (Exception ex)
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
private final InetSocketAddress server;
public ChatClient(InetSocketAddress server)
this.server = server;
public void run() throws Exception
EventLoopGroup group = new NioEventLoopGroup();
try
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChatClientInitializer());
Channel channel = bootstrap.connect(server).sync().channel();
System.out.println("Connected to Server: " + server.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (channel.isActive())
String userMessage = in.readLine();
channel.writeAndFlush(userMessage + "\r\n");
if (userMessage.equalsIgnoreCase("bye"))
group.shutdownGracefully();
break;
finally
group.shutdownGracefully();
ChatClientInitializer.java
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;
public class ChatClientInitializer extends ChannelInitializer<SocketChannel>
@Override
protected void initChannel(SocketChannel c) throws Exception
ChannelPipeline pipeline = c.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new ChatClientHandler());
ChatClinetHandler.java
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ChatClientHandler extends ChannelInboundHandlerAdapter
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
System.out.println(msg.toString());
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause)
cause.printStackTrace();
【问题讨论】:
【参考方案1】:对不起,我忘记在每条消息中发送“\r\n”。
【讨论】:
【参考方案2】:虽然shim_ claims to have determined that the problem is not sending "\r\n" with each message,但我认为有必要在此澄清一下。
在 ChatClientInitializer.java 中,您会看到一个名为 framer 的处理程序,它是一个 DelimiterBasedFrameDecoder
对象,在该特定示例中带有行分隔符(有关 DelimiterBasedFrameDecoder 的更多信息,请参见 here)。
因此,这意味着客户端期望在该特定频道上以 "\r\n" 结尾的消息。如果收到不以"\r\n"结尾的消息,则不会触发channelRead()
方法。
【讨论】:
以上是关于Netty channelRead 从未调用过的主要内容,如果未能解决你的问题,请参考以下文章
Netty中为啥执行channelReadComplete但是不执行channelRead
netty channelhandleradapter 是否去了channelread方法