netty获取玩家chanel_基于netty的TCP服务端如何给客户端发送消息,但是如何拿到客户端连接时的SocketChannel呢,菜鸟求助?...
1.思路1
每个客户端连接时的SocketChannel保存在会话类sessionManager中的sessionIdMap中
问题:
1.客户端连接时确实将SocketChannel保存在会话类sessionManager中的sessionIdMap中了,
但是只能在TCPServerHandle这个类中拿到储存有session的sessionManager
2.出了这个类就无法获取到保存的session了,也就拿不到SocketChannel,所以无法给客户端发消息了.
应该如何解决呢?
注:以下代码用的是诸葛流云大佬的中的代码,菜鸟求助
sessionManager类如下:
public class SessionManager {
private static volatile SessionManager instance = null;
// netty生成的sessionID和Session的对应关系
private Map sessionIdMap;
// 终端手机号和netty生成的sessionID的对应关系
private Map phoneMap;
public static SessionManager getInstance() {
if (instance == null) {
synchronized (SessionManager.class) {
if (instance == null) {
instance = new SessionManager();
}
}
}
return instance;
}
public SessionManager() {
this.sessionIdMap = new ConcurrentHashMap<>();
this.phoneMap = new ConcurrentHashMap<>();
}
public boolean containsKey(String sessionId) {
return sessionIdMap.containsKey(sessionId);
}
public boolean containsSession(Session session) {
return sessionIdMap.containsValue(session);
}
public Session findBySessionId(String id) {
return sessionIdMap.get(id);
}
public Session findByTerminalPhone(String phone) {
String sessionId = this.phoneMap.get(phone);
if (sessionId == null)
return null;
return this.findBySessionId(sessionId);
}
public synchronized Session put(String key, Session value) {
if (value.getTerminalPhone() != null && !"".equals(value.getTerminalPhone().trim())) {
this.phoneMap.put(value.getTerminalPhone(), value.getId());
}
return sessionIdMap.put(key, value);
}
public synchronized Session removeBySessionId(String sessionId) {
if (sessionId == null)
return null;
Session session = sessionIdMap.remove(sessionId);
if (session == null)
return null;
if (session.getTerminalPhone() != null)
this.phoneMap.remove(session.getTerminalPhone());
return session;
}
public Set keySet() {
return sessionIdMap.keySet();
}
public Set> entrySet() {
return sessionIdMap.entrySet();
}
public List toList() {
List list = new ArrayList<>();
Set> entrySet = this.sessionIdMap.entrySet();
for (Entry entry : entrySet) {
Session session = entry.getValue();
list.add(session);
}
return list;
}
}
客户端连接时保存SocketChannel:
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Session session = Session.buildSession(ctx.channel());
sessionManager.put(session.getId(), session);
logger.debug("终端连接:{}", session);
}
TCP服务端处理器如下:
public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1)
private final Logger logger = LoggerFactory.getLogger(getClass());
private final SessionManager sessionManager;
private final MsgDecoder decoder;
private TerminalMsgProcessService msgProcessService;
private HandleTcpInformation handleTcpInformation;
public TCPServerHandler() {
this.sessionManager = SessionManager.getInstance();
this.decoder = new MsgDecoder();
this.msgProcessService = new TerminalMsgProcessService();
this.handleTcpInformation = new HandleTcpInformation();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws InterruptedException { // (2)
try {
ByteBuf buf = (ByteBuf) msg;
if (buf.readableBytes() <= 0) {
// ReferenceCountUtil.safeRelease(msg);
return;
}
byte[] bs = new byte[buf.readableBytes()];
buf.readBytes(bs);
// 字节数据转换为针对于808消息结构的实体类
PackageData pkg = this.decoder.bytes2PackageData(bs);
// 引用channel,以便回送数据给硬件
pkg.setChannel(ctx.channel());
logger.info(pkg.toString());
// 对808消息结构的实体类进行逻辑处理
this.processPackageData(pkg);
} finally {
release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
logger.error("发生异常:{}", cause.getMessage());
cause.printStackTrace();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Session session = Session.buildSession(ctx.channel());
sessionManager.put(session.getId(), session);
logger.debug("终端连接:{}", session);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
final String sessionId = ctx.channel().id().asLongText();
Session session = sessionManager.findBySessionId(sessionId);
this.sessionManager.removeBySessionId(sessionId);
logger.debug("终端断开连接:{}", session);
ctx.channel().close();
// ctx.close();
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state() == IdleState.READER_IDLE) {
Session session = this.sessionManager.removeBySessionId(Session.buildId(ctx.channel()));
logger.error("服务器主动断开连接:{}", session);
ctx.close();
}
}
}
private void release(Object msg) {
try {
ReferenceCountUtil.release(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
netty获取玩家chanel_基于netty的TCP服务端如何给客户端发送消息,但是如何拿到客户端连接时的SocketChannel呢,菜鸟求助?...相关推荐
- netty tcp服务端主动断开客户端_【Netty】服务端和客户端
欢迎关注公众号:[爱编程] 如果有需要后台回复2019赠送1T的学习资料哦!! 本文是基于Netty4.1.36进行分析 服务端 Netty服务端的启动代码基本都是如下: private void s ...
- netty tcp服务端主动断开客户端_「Netty核心技术」6-ChannelPipeline源码
ChannelPipeline是Channelhandler的容器,它负责ChannelHandler的管理和事件拦截与调度. 土话: ChannelPipeline就是用来管理Channelhand ...
- netty获取玩家chanel_我是怎样阅读 Netty Channel 源码的
Channel 功能说明 我在使用 ServerBootstrap 来创建服务的时候通过 channel(NioServerSocketChannel.class) 来设置 Channel, 那么 C ...
- QT 之 TCP 服务端 连接 多客户端 处理学习
自学QT中, 在此记录一下TCP多链接的方法. 跟着 "Qt Creator快速入门" 学了一段时间了,刚接触网络编程, 例子中仅仅简单的 用 客户端 连接了一下 服务端, 然后 ...
- tcp 服务端如何判断客户端断开连接
最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条socket连接.这就涉及到一个 ...
- 网络编程之TCP服务端程序开发
TCP服务端程序开发 学习目标 能够写出TCP服务端应用程序接收和发送消息 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 ...
- c/c++基于liunx平台tcp协议通信分数据段发送小demo
引言*:tcp 是网络通信的一种协议,协议的话对于程序员来说就是按照约定的协议编写程序即可,具体编码的话相对于 之前做过的 socket 通信的 demo 来说 socket 通信来说并不会使用全新的 ...
- 采用netty开发智能手表tcp服务端还是非常不错的
采用netty开发智能手表tcp服务端还是非常不错的,经过单服务部署测试并发能达到10w,可以用于开发开发马蹄锁,儿童智能手表,其他智能设备,物联网等等,有啥有趣好玩的物联网可以进行交流一下
- 《netty入门与实战》笔记-02:服务端启动流程
为什么80%的码农都做不了架构师?>>> 1.服务端启动流程 这一小节,我们来学习一下如何使用 Netty 来启动一个服务端应用程序,以下是服务端启动的一个非常精简的 Demo ...
最新文章
- Java项目:(前端vue后台java微服务)在线考试系统(java+vue+springboot+mysql+maven)
- 这玩意比ThreadLocal叼多了,吓得我赶紧分享出来。
- 这个安全平台结合Spring Security逆天了,我准备研究一下
- 全球及中国医药销售外包(CSO)产业营销创新模式市场格局分析报告2022版
- Java3y文章目录导航
- jmh 基准测试_JMH:如何设置和运行JMH基准
- Linux的实际操作:任务调度基本说明
- 如何评估深度学习模型效果?阿里工程师这么做 1
- Matplotlib 中文用户指南 8.1 屏幕截图
- 一步一步学习ObjectDataSource--(3)
- 弹出ifame页面(jquery.reveal.js)
- 再生核希尔伯特空间和核方法
- python网络测速_网络测速命令--speedtest
- kdj买卖指标公式源码_通达信一品KDJ波段买卖操作源码免费指标公式
- 通信网络定级备案怎么做?工信部信息系统定级备案流程介绍
- 本市医保定点专科医院、定点中医院及19家A类医疗机构
- 计算机网络---通过DNS服务器查询Web服务器的IP地址
- 禁用uwebiview 的反弹功能 bounces
- python计算时间差的方法_如何计算时间差,用Python算法的话
- 标准模板库STL(Standard Template Library)