问题出现:客户端能够发送消息至服务端,服务端广播的消息在客户端接收不到
Client端
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
.addLast(new TankJoinMsgEncoder()) // 客户端通过编码发送至服务端
.addLast(new TankJoinMsgDecoder()) // 服务端解码服务端广播的消息
.addLast(new ClientHandler());
}
}
class ClientHandler extends SimpleChannelInboundHandler<TankJoinMsg> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TankJoinMsg msg) throws Exception {
if(msg.id.equals(TankFrame.INSTANCE.getMainTank().getId()) ||
TankFrame.INSTANCE.findByUUID(msg.id)!=null ) return;
System.out.println(msg);
Tank t = new Tank(msg);
TankFrame.INSTANCE.addTank(t);
ctx.writeAndFlush(new TankJoinMsg(TankFrame.INSTANCE.getMainTank())); // 发送消息至server端
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(new TankJoinMsg(TankFrame.INSTANCE.getMainTank()));// 会通过TankJoinMsgEncoder编码,编完之后才会写到服务器
}
}
Server端
public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
public void serverStart() {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(2);
ServerBootstrap sb = new ServerBootstrap(); // 辅助启动类
try {
ChannelFuture f = sb.group(bossGroup,workerGroup) // 指定线程池组
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pl = socketChannel.pipeline();
pl.addLast(new TankJoinMsgDecoder())
.addLast(new ServerChildHandler());
}
})
.bind(9999)
.sync();
ServerFrame.INSTANCE.updateServerMsg("server started!");
f.channel().closeFuture().sync(); // close->ChannelFuture
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
class ServerChildHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Server.clients.add(ctx.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
// 删除出现异常的客户端channel,并关闭连接
Server.clients.remove(ctx.channel());
ctx.close();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ServerFrame.INSTANCE.updateClientMsg(msg.toString());
Server.clients.writeAndFlush(msg);
}
}
通过一番检查,才发现原因是在Server端下没有增加消息编码,导致Client端无法接收到数据
处理方法:
ChannelFuture f = sb.group(bossGroup,workerGroup) // 指定线程池组
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pl = socketChannel.pipeline();
pl.addLast(new TankJoinMsgDecoder())
.addLast(new TankJoinMsgEncoder()) // 该位置加上消息编码
.addLast(new ServerChildHandler());
}
})
.bind(9999)
.sync();