netty框架--实现一个聊天功能
netty框架--实现一个聊天功能。
最近在学习netty框架,netty框架为异步非阻塞IO框架,比起传统的BIO,性能,并发性更为可靠。
如下为一个netty的聊天小程序:
首先编写客户端启动类 ChatClient.java
import java.io.BufferedReader; import java.io.InputStreamReader; 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; public class ChatClient { private final int port; private final String host; public ChatClient(String host, int port) { this.host = host; this.port = port; } public void run() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class).handler(new ChatChannelInitializer()); Channel channel = b.connect(host, port).sync().channel(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { String msg = in.readLine(); channel.writeAndFlush( msg+ "\r\n"); } } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new ChatClient("10.0.90.93",8080).run(); } }
添加通道初始化类 ChatChannelInitializer,添加各种处理类及本的处理类。
import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; 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 ChatChannelInitializer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("framer",new DelimiterBasedFrameDecoder(1024,Delimiters.lineDelimiter())); p.addLast("StringDecoder",new StringDecoder()); p.addLast("StringEncoder",new StringEncoder()); p.addLast("handler",new ChatClientHander()); } }
通道I/O处理类 ChatHandler
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; public class ChatClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); } }
服务端编写:
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; public class ChatServer { private final int port; public ChatServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChatServerInitializer()); b.bind(port).sync().channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new ChatServer(8080).run(); } }
package com.phei.netty.chat; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; 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 ChatServerInitializer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("framer",new DelimiterBasedFrameDecoder(1024,Delimiters.lineDelimiter())); p.addLast("StringDecoder", new StringDecoder()); p.addLast("StringEncoder", new StringEncoder()); p.addLast("handler", new ChatServerHandler()); } }
服务端处理类,此类服务监听各Chat客户端的连入,退出,以及分发客户端发送的消息等。
import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.DefaultEventExecutorGroup; public class ChatServerHandler extends SimpleChannelInboundHandler<String> { private final static ChannelGroup channels = new DefaultChannelGroup(new DefaultEventExecutorGroup(1).next()); @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { Channel incoming = ctx.channel(); for (Channel ch : channels) { if (ch != incoming) { ch.writeAndFlush("[" + incoming.remoteAddress() + "] - " + msg + "\r\n"); } } } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); for(Channel ch :channels) { ch.writeAndFlush("[SERVER] - "+channel.remoteAddress() +" has joined.\r\n"); } channels.add(channel); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); for(Channel ch :channels) { ch.writeAndFlush("[SERVER] - "+channel.remoteAddress() +" has left.\r\n"); } channels.remove(channel); } }

浙公网安备 33010602011771号