マルチプレイヤーゲーム用の単純な netty サーバーを実装しています。私はNettyを理解しようとしています。
telnet経由でサーバーをテストします。私がしたことは、メッセージをすべてのチャネルにブロードキャストすることです。順調に稼働中です。また、閉じるイベントでマップからチャネルを削除しますが、これは問題ありません。
ただし、問題は、クライアントの 1 つが予期せず切断された場合です。コールバックが閉じられる前に、送信者がチャネルを切断した messageReceived コールバックが呼び出されます。
切断されたクライアントからのメッセージを適切に無視するにはどうすればよいですか? 私は使用StringBuffer
しますmessagedReceived
が、ケースStringBuffer.toString
も適切な文字列ではありません。最後に、切断されたチャネルは他のチャネルとそれ自体に無意味なメッセージをブロードキャストします。レシーバーチャネル自体が例外Connection reset by peer
をスローする場合、チャネル自体は現在利用できないため、これは正常です。
コードは次のとおりです。
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
System.out.println();
System.out.println("------------------");
Channel current = e.getChannel();
System.out.println("SenderChannel:"+current.getId());
if(!current.isOpen())
System.out.println("Not Open");
ChannelBuffer buf = (ChannelBuffer) e.getMessage();
StringBuffer sbs = new StringBuffer();
while(buf.readable()) {
sbs.append((char) buf.readByte());
}
String s = sbs.toString();
System.out.println(s);
String you = "You:" + s;
String other = "Other:" + s;
byte [] uResponse = you.getBytes();
byte [] otherResponse = other.getBytes();
Iterator iterator = channelList.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry pairs = (Map.Entry)iterator.next();
Integer key = (Integer)pairs.getKey();
Channel c = (Channel)pairs.getValue();
System.out.println("ReceiverChannel:"+c.getId());
if(key != current.getId())
c.write(ChannelBuffers.wrappedBuffer(otherResponse));
else
c.write(ChannelBuffers.wrappedBuffer(uResponse));
}
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx,
ChannelStateEvent e){
Channel ch = e.getChannel();
channelList.remove(ch.getId());
System.out.println();
System.out.println("*****************");
System.out.println("DisconnectEvent:"+ch.getId());
System.out.println("*****************");
System.out.println();
ch.close();
}