利用netty簡單實現聊天室
阿新 • • 發佈:2018-11-27
1.匯入依賴包
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha1</version> </dependency>
2.netty服務端程式碼
public class NettyServer { public static void main(String[] args) { EventLoopGroup bossGroup= new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap bootStrap = new ServerBootstrap(); ChannelFuture cf; bootStrap.group(bossGroup,workGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG,1024) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("decoder", new StringDecoder());//需要編解碼,否則無法解析 p.addLast("encoder", new StringEncoder()); p.addLast(new NettyServerHandler()); } }); try { cf = bootStrap.bind(8099).sync();//監聽8099埠 System.out.println("8099:binded..."); cf.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }
3.netty客戶端程式碼
public class NettyClient { public static void main(String[] args) throws Exception { EventLoopGroup group =new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>(){ @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("decoder", new StringDecoder()); p.addLast("encoder", new StringEncoder()); p.addLast(new ClientHandler()); p.addLast(new ClientHandlerBak()); } }); ChannelFuture future = b.connect("127.0.0.1", 8099).sync(); future.channel().writeAndFlush("這裡是客戶端,請求連線服務端!"); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } }
4.服務端處理類
public class NettyServerHandler extends ChannelHandlerAdapter { //有客戶端連線時觸發 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("one client connect..."); } //斷開連線時觸發 @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("one client disconnect..."); } //接收客戶端傳送的訊息 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("客戶端:"+msg.toString()); InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); String result ="result"; try{ result = br.readLine(); } catch(IOException e){ e.printStackTrace(); } ctx.write(result);//給客戶端回覆 ctx.flush(); } }
5.客戶端處理類
public class ClientHandler extends ChannelHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("Client01Handler Active"); /*若把這一句註釋掉將無法將event傳遞給下一個ClientHandler,例如例子中p.addLast(new Client01Handler())後面緊跟著p.addLast(new Client02Handler()) 後面的Client02Handler裡的方法就不會被觸發。 */ ctx.fireChannelActive(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("服務端: "+msg); InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); String result ="result"; try{ result = br.readLine(); } catch(IOException e){ e.printStackTrace(); } ctx.write(result);//給服務端回覆 ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
6.最後,看看效果,先啟動服務端,再啟動客戶端