この記事は、「新人クリエーションセレモニー」イベントに参加し、一緒にゴールドクリエーションの道を歩み始めました。
最初に知っておくべきことは、nettyはマルチスレッドであるということです。これはSocketに基づいています。
1:以前は、ブロガーはnettyでListを使用してchannelIdを保存し、それを一意に識別していましたが、1つのポイントを無視しました。Listは安全ではありません。特にマルチスレッド環境では、データの混乱の問題が発生します。
2:セキュリティ上の理由から、マップの形式が再び採用されます。channelIdにアクセスするためだけに使用される場合は、間違いなく問題はありません。しかし、複数のインターフェースがこのマップを呼び出す場合はどうなるでしょうか。何かがおかしいようです。
3:ブロガー側の環境は、データを内部ネットワークにプッシュする外部ネットワークアプリケーションです。ここでのchannelIdへのアクセスは、アクセスに使用するキャッシュを考慮せず、staticによって直接共有されます。
解決:
接続時:
1:クライアント接続がある場合は、クライアントのchannelIdを記録します。
2:接続を確立し、メッセージを返します
切断時:
1:クライアントはサーバーをアクティブに切断し、ストリームを閉じます。
2:切断
/**
* 当有客户端连接时,handlerAdded会执行,就把该客户端的通道记录下来,加入队列
* 连接第1步
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channels.add(channel);
super.handlerAdded(ctx);
}
/**
* 建立连接时,返回消息
* 连接第2步
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
AttributeKey<String> host_channel_key = AttributeKey.valueOf("channel-host");
Attribute<String> attr = channel.attr(host_channel_key);
InetSocketAddress socketAddress = (InetSocketAddress) channel.remoteAddress();
String host = socketAddress.getHostString();
attr.set(host);
log.debug("通道号:[{}],客户端:[{}]: 在线",channel.toString(), channel.remoteAddress());
super.channelActive(ctx);
}
/**
* 客户端主动断开服务端的链接,关闭流
* */
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
log.debug("通道号:[{}],客户端:[{}]: 离线",channel.toString(), channel.remoteAddress());
super.channelInactive(ctx);
}
/**
* 断开连接 第2步
*
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channels.remove(channel);
super.handlerRemoved(ctx);
ctx.channel().close();
}
复制代码
最も重要なステップ。
public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
DefaultChannelGroupクラスのaddメソッドを見てください
それを忘れてください、それはマルチスレッドであるかどうかです。それは私たちが現在のニーズを満たすことができるかどうかに依存します。Channel channel = ctx.channel();channels.add(channel);これまでのところchannelIdを本来あるべき場所に配置しました。
次に、最初に戻ります。nettyは、マルチスレッドかどうかです。ブロガーの能力は限られており、興味のある人は自分で見に行くことができます。