netty示例-netty聊天室
1.MyChatServer.java
public class MyChatServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new TestMyChatServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(8989).sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}2.TestMyChatServerHandler.java
public class TestMyChatServerHandler extends SimpleChannelInboundHandler<String>{
private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
// ChannelGroup 是获取到 所有的客户端 连接的channle
@Override
protected void channelRead0(ChannelHandlerContext paramChannelHandlerContext, String msg) throws Exception {
//当任意一个客户端连接上服务端时,就会执行的方法
Channel channel = paramChannelHandlerContext.channel();
channelGroup.forEach(ch -> {
if(channel!=ch){
ch.writeAndFlush(channel.remoteAddress()+"发送的消息"+msg+"\n");
}else{
ch.writeAndFlush("[自己]"+msg+"\n");
}
});
// 对上述ch -> 的解析代码
// channelGroup.forEach(new Consumer<Channel>() {
// @Override
// public void accept(Channel t) {
// if(channel!=t){
// t.writeAndFlush(channel.remoteAddress()+"发送的消息"+msg+"\n");
// }else{
// t.writeAndFlush("[自己]"+msg+"\n");
// }
// }
// });
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channelGroup.writeAndFlush("[服务器]"+channel.remoteAddress()+"加入\n");
channelGroup.add(channel);//这两句是先广播其他服务器,再加入自己
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channelGroup.writeAndFlush("[服务器]"+channel.remoteAddress()+"退出\n");
// channelGroup.remove(channel);实际上这句可以不用加,因为当连接断开后,会将channel自动断开
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
System.out.println(channel.remoteAddress()+"上线了\n");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
System.out.println(channel.remoteAddress()+"下线了\n");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}3.MyChatClient.java
public class MyChatClient {
public static void main(String[] args) {
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter()));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new TestMyChatClientHandler());
}
});
Channel channel = bootstrap.connect("localhost",8989).sync().channel();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
for(;;){
channel.writeAndFlush(reader.readLine()+"\r\n");
}//创造死循环,读取键盘输入的信息
} catch (Exception e) {
e.printStackTrace();
}finally {
eventLoopGroup.shutdownGracefully();
}
}
}4.TestMyChatClientHandler.java
public class TestMyChatClientHandler extends SimpleChannelInboundHandler<String>{
@Override
protected void channelRead0(ChannelHandlerContext paramChannelHandlerContext, String msg) throws Exception {
System.out.println(msg);
}
}5.TcpHandler拦截器解答
DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter()); //4096是maxFrameLengthDelimiterBasedFrameDecoder用来解决以特殊符号作为消息结束符的粘包问题,本例中用到的是”\r\n”和“\n”。
ChannelGroup 是获取到所有的客户端连接的channle 。故可以进行广播处理。
文章标题:netty示例-netty聊天室
发布时间:2020-01-17, 09:52:45
最后更新:2020-01-17, 09:52:45