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呢,菜鸟求助?...相关推荐

  1. netty tcp服务端主动断开客户端_【Netty】服务端和客户端

    欢迎关注公众号:[爱编程] 如果有需要后台回复2019赠送1T的学习资料哦!! 本文是基于Netty4.1.36进行分析 服务端 Netty服务端的启动代码基本都是如下: private void s ...

  2. netty tcp服务端主动断开客户端_「Netty核心技术」6-ChannelPipeline源码

    ChannelPipeline是Channelhandler的容器,它负责ChannelHandler的管理和事件拦截与调度. 土话: ChannelPipeline就是用来管理Channelhand ...

  3. netty获取玩家chanel_我是怎样阅读 Netty Channel 源码的

    Channel 功能说明 我在使用 ServerBootstrap 来创建服务的时候通过 channel(NioServerSocketChannel.class) 来设置 Channel, 那么 C ...

  4. QT 之 TCP 服务端 连接 多客户端 处理学习

    自学QT中, 在此记录一下TCP多链接的方法. 跟着 "Qt Creator快速入门" 学了一段时间了,刚接触网络编程, 例子中仅仅简单的 用 客户端 连接了一下 服务端, 然后 ...

  5. tcp 服务端如何判断客户端断开连接

    最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条socket连接.这就涉及到一个 ...

  6. 网络编程之TCP服务端程序开发

    TCP服务端程序开发 学习目标 能够写出TCP服务端应用程序接收和发送消息 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 ...

  7. c/c++基于liunx平台tcp协议通信分数据段发送小demo

    引言*:tcp 是网络通信的一种协议,协议的话对于程序员来说就是按照约定的协议编写程序即可,具体编码的话相对于 之前做过的 socket 通信的 demo 来说 socket 通信来说并不会使用全新的 ...

  8. 采用netty开发智能手表tcp服务端还是非常不错的

    采用netty开发智能手表tcp服务端还是非常不错的,经过单服务部署测试并发能达到10w,可以用于开发开发马蹄锁,儿童智能手表,其他智能设备,物联网等等,有啥有趣好玩的物联网可以进行交流一下

  9. 《netty入门与实战》笔记-02:服务端启动流程

    为什么80%的码农都做不了架构师?>>>    1.服务端启动流程 这一小节,我们来学习一下如何使用 Netty 来启动一个服务端应用程序,以下是服务端启动的一个非常精简的 Demo ...

最新文章

  1. Java项目:(前端vue后台java微服务)在线考试系统(java+vue+springboot+mysql+maven)
  2. 这玩意比ThreadLocal叼多了,吓得我赶紧分享出来。
  3. 这个安全平台结合Spring Security逆天了,我准备研究一下
  4. 全球及中国医药销售外包(CSO)产业营销创新模式市场格局分析报告2022版
  5. Java3y文章目录导航
  6. jmh 基准测试_JMH:如何设置和运行JMH基准
  7. Linux的实际操作:任务调度基本说明
  8. 如何评估深度学习模型效果?阿里工程师这么做 1
  9. Matplotlib 中文用户指南 8.1 屏幕截图
  10. 一步一步学习ObjectDataSource--(3)
  11. 弹出ifame页面(jquery.reveal.js)
  12. 再生核希尔伯特空间和核方法
  13. python网络测速_网络测速命令--speedtest
  14. kdj买卖指标公式源码_通达信一品KDJ波段买卖操作源码免费指标公式
  15. 通信网络定级备案怎么做?工信部信息系统定级备案流程介绍
  16. 本市医保定点专科医院、定点中医院及19家A类医疗机构
  17. 计算机网络---通过DNS服务器查询Web服务器的IP地址
  18. 禁用uwebiview 的反弹功能 bounces
  19. python计算时间差的方法_如何计算时间差,用Python算法的话
  20. 标准模板库STL(Standard Template Library)

热门文章

  1. 调频连续波逆合成孔径雷达(FMCW-ISAR)对舰船目标成像脉内补偿方法的研究
  2. java override例子_java经常碰到的@Override标签
  3. video标签实现视频播放和进度显示
  4. 美国计算机专业的大学,美国计算机专业大学排名
  5. IDEA 导入jar包和使用jar包方法
  6. bootstrap中datetimepicker显示1899问题
  7. 系统日志截图 服务器,域策略错误截图及日志截图
  8. 盘点5个情人节反向营销案例:哪个品牌最得你心
  9. Linux-Squid代理服务器搭建
  10. RTC 2017实时互联网大会会议总结、数据收集