例えば第二のコードに基づいて、複数のクライアント接続、ライブチャットをサポートしています。
主なアイデア:
接続が確立されると保存されたチャネルのコレクションを横断するとき、新しいクライアントが参加したときに、サーバ側では、チャネルオブジェクトを保存し、参加するために他のクライアントにメッセージを送信します。
クライアントがメッセージ、サーバー側に送信する際、送信者が修正されたコンテンツを送信するかどうかを決定するために設定されたチャネルを横切る、例えば:XXは言った:私は言いました:
同じ:
第二の例のメインサーバは同様です
初期化子内のサーバー
1つの インポートio.netty.channel.ChannelInitializer。 2 インポートio.netty.channel.ChannelPipeline。 3 輸入io.netty.channel.socket.SocketChannel。 4 インポートio.netty.handler.codec.DelimiterBasedFrameDecoder。 5 輸入io.netty.handler.codec.Delimiters。 6 インポートio.netty.handler.codec.string.StringDecoder。 7 インポートio.netty.handler.codec.string.StringEncoder。 8 インポートio.netty.util.CharsetUtil。 9つの 10 パブリック クラス MyChatServerInitlalizerが延びていますChannelInitializer <たSocketChannel> { 11 12 @Override 13 保護 空隙 initChannel(のSocketChannel CH)スロー例外{ 14 ChannelPipelineパイプライン= ch.pipelineを(); 15 // 解码器、根据分隔符来分割 16 pipeline.addLast(新しい DelimiterBasedFrameDecoder(4096 、Delimiters.lineDelimiter()))。 17 pipeline.addLast(新しい StringDecoder(CharsetUtil.UTF_8)); // 编码 18 pipeline.addLast(新しい StringEncoder(CharsetUtil.UTF_8)); //解码 19 20 pipeline.addLast(新しいMyChatServerHandler())。 21 22 } 23 }
ハンドラサーバ
1 インポートio.netty.channel.Channel; 2 インポートio.netty.channel.ChannelHandlerContext; 3 インポートio.netty.channel.SimpleChannelInboundHandler; 4 インポートio.netty.channel.group.ChannelGroup; 5 インポートio.netty.channel。 group.DefaultChannelGroup; 6 インポートio.netty.util.concurrent.GlobalEventExecutor; 7 8。 パブリック クラス MyChatServerHandler 延び SimpleChannelInboundHandler <ストリング> { 9。 10 // このオブジェクトは、すべてのチャネルを取得することができる 11。 プライベート スタティックチャネル・グループチャネル・グループ= 新しいDefaultChannelGroup(GlobalEventExecutor.INSTANCE)。 12 13 14 @Override 15 公共 ボイド exceptionCaught(ChannelHandlerContext CTX、Throwableの原因)がスロー例外{ 16 cause.printStackTraceを(); 17 ctx.close()。 18 } 19 20 @Override 21 保護 ボイド channelRead0(ChannelHandlerContext CTX、文字列MSG)はスロー例外{ 22 チャネルのチャネル= ctx.channelを(); 23 24 channelGroup.forEach(CH - > { 25 のSystem.out.println( "II" ) 26は、 IF(CH =!チャネル){ 27 のSystem.out.println( "othor" ); 28 ch.writeAndFlush(channel.remoteAddress( )+ "送信されたメッセージ:" MSG + + "\ N-"); // ときの\ N-メッセージを送信、にできそうでない場合、失われてはならない 29 } 他{ 30 ch.writeAndFlush( "自分自身:" MSG + + "\ N-" ); 31である } 32 }); 33は、 34である // サーバがメッセージを受信し、クライアントはすべての位相にメッセージを送信する 35 System.out.println(+ channel.remoteAddress()+ "クライアントメッセージ:" "受信" + MSG)を、 36 // // 他のクライアントに送信される 37 // ctx.writeAndFlush( "MSG"); 38れます } 39 40 @Override 41は 公共 ボイド handlerAddedは(ChannelHandlerContext CTX)がスロー例外{ 42は チャネルチャネルctx.channel =(); // 取得接続 43 //は他の既存の接続言う 44は channelGroup.writeAndFlush(「[サーバ] - "+ channel.remoteAddress()+" - 「N- \添加); 45 //が追加 46 channelGroup.add(チャネル); // チャネルがチャネル・グループに追加された 47 } 48 49 @Override 50 公共 ボイド handlerRemoved(ChannelHandlerContext CTX)はスロー{例外 51が チャンネルチャネル= ctx.channel()は、 52である channelGroup.writeAndFlush(「[サーバ] - "+ channel.remoteAddress()+"「N- \残っている); 53である // ; channelGroup.remove(チャネル)// 網状に自動的に接続チャンネルを失っているので、チャネル・グループから除去され 54である } 55 56れる @Override 57 公共 のボイドchannelActive(ChannelHandlerContext CTX)がスロー例外{ 58 チャネルのチャネル= ctx.channelを(); 59 のSystem.out.println(channel.remoteAddress()+ "上线了!" ); 60 } 61 62 @Override 63 公共 ボイド channelInactive(ChannelHandlerContext CTX)がスロー例外{ 64 チャネルのチャネル= ctx.channelを(); 65 のSystem.out.println(channel.remoteAddress()+ "下线了!" ); 66 } 67 }
メインCLIEN
1つの インポートio.netty.bootstrap.Bootstrap。 2 インポートio.netty.channel.Channel。 3 インポートio.netty.channel.ChannelFuture。 4 インポートio.netty.channel.EventLoopGroup。 5 インポートio.netty.channel.nio.NioEventLoopGroup。 6 インポートio.netty.channel.socket.nio.NioSocketChannel。 7 8 インポートjava.io.BufferedReader。 9 インポートにjava.io.IOException。 10 インポートjava.io.InputStreamReader。 11 12 パブリック クラスMyChatClient { 13 公衆 静的 ボイドメイン(文字列[]引数)スローInterruptedExceptionあるは、IOException { 14 // 客户端只需要一个 15 EventLoopGroup eventLoopGroup = 新しいNioEventLoopGroupを(); 16 17 のtry { 18 19 ブートストラップブートストラップ= 新しいブートストラップ()。 20 bootstrap.group(eventLoopGroup) 21 .channel(NioSocketChannel。クラス) 22 .handler(新しいMyChatInitlaizer())。 23 = Bootstrap.connect ChannelFuture ChannelFuture( "ローカルホスト"、8899 ).sync(); 24 25 チャネルチャネル= channelFuture.channel(); 26である 27 // channelFuture.channel()writeAndFlush( "まずMSG");. // 送信実際に、アクティブハンドラメソッドに書き込まれるべきデータ 28 29 BufferedReaderのBR = 新しい新しい BufferedReaderの(新しい新しいInputStreamReaderの(System.in)); 30 のための(;;){ // 受信側クライアントに無限ループの入力 31は channel.writeAndFlush(BR .readline()+ "\ R&LT \ N-" ); 32 } 33である 34れる // 。channelFuture.channel()closeFuture()同期()。 35 } 最後に{ 36 eventLoopGroup.shutdownGracefully()。 37 } 38 39 } 40 }
同様に、クライアントとサーバーの初期化子
ハンドル内のクライアント、ライン上で簡単に出力。