4、ネッティー第三の例、TCPのチャットプログラムを確立します

例えば第二のコードに基づいて、複数のクライアント接続、ライブチャットをサポートしています。

主なアイデア:

  接続が確立されると保存されたチャネルのコレクションを横断するとき、新しいクライアントが参加したときに、サーバ側では、チャネルオブジェクトを保存し、参加するために他のクライアントにメッセージを送信します。

  クライアントがメッセージ、サーバー側に送信する際、送信者が修正されたコンテンツを送信するかどうかを決定するために設定されたチャネルを横切る、例えば: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 }

 

同様に、クライアントとサーバーの初期化子

ハンドル内のクライアント、ライン上で簡単に出力。

 

おすすめ

転載: www.cnblogs.com/amibandoufu/p/11442739.html