netty4,服务端向客户端主动发消息怎么把channel存储到redis缓存中?

怎么把netty的链接通道存储到redis中这样后续可以通过key取出channel给客户端发消息

阅读 26.3k
9 个回答

我的理解是题主要做netty分布式服务,
一般而言 netty 连接都是统一保存在map<key,Channel>中,key值为用户标识,主要问题在与多节点时,需要向用户发送消息如何知道用户在哪个节点上
解决方案有下面几种:
1.在redis 中存储一张路由表,记录用户所在服务节点,然后发送消息。
2.利用mq 统一向所有节点广播消息(消息内附带用户信息),节点收到消息后判断用户是否连接在本节点上,如果在则从map 中取出,并发送消息,否则丢弃.
3.另一种也是一种查找路由的方式,利用一致性Hash算法,查找用户所在服务节点.

我们项目中大致是这么做的:
无论是自己写数据结构还是使用Jedis,大概都是有一个类似Map的结构。

  • 建立一个Bean用于表示会话,此处暂且称之为Session。

  • 在Session里引用netty的Channel。

  • channelActive时将其放入redis。

  • 有必要的话,可以将channel.id().asLongText()channel.id().asShortText()作为Session的唯一标识

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    //可以将channel.id().asLongText()或channel.id().asShortText()作为Session的ID
    Session session = Session.buildSession(ctx.channel());
    //Session存入Redis
    pushSession2Redis(session);
    logger.info("终端连接:{}", session);
}

Session.java

import java.net.SocketAddress;
import io.netty.channel.Channel;

public class Session {
    //Session的唯一标识
    private String id;
    //和Session相关的channel,通过它向客户端回送数据
    private Channel channel = null;
    //上次通信时间
    private long lastCommunicateTimeStamp = 0l;

    //快速构建一个新的Session    
    public static Session buildSession(Channel channel) {
        Session session = new Session();
        session.setChannel(channel);

        //此处暂且使用netty生成的类似UUID的字符串,来标识一个session
        session.setId(channel.id().asLongText());
        session.setLastCommunicateTimeStamp(System.currentTimeMillis());
        return session;
    }

    // getter,setter
}
public class SessionManager{

    //将Session放入redis
    public void pushSession2Redis(Session  session){
        //这里就不用我说了吧
        //不知道你自己用的redis客户端是什么
        //调用客户端(比如Jedis)的API把session放到你自己的数据结构不就行了
    }
    
    //从redis获取指定session
    public Session findById(String sessionId){
        return null;
    }
}
新手上路,请多包涵

你确定你这个能序列化保存到redis里面?

新手上路,请多包涵

您好 请问现在有解决方案了么

图片描述

  • 或许这里要注意一下?
新手上路,请多包涵

我也遇到这个问题了?请问一下你解决了吗?

新手上路,请多包涵

我按照@诸葛流云的方式试了,但是向redis中保存的时候,还是报不能序列化的异常,暂时没找到合适的方案
2018年3月22日09:18:19

放内存里面了,之前是要做集群想存redis所有机器都能取出来用后来发现不是这么回事

新手上路,请多包涵

解决了吗?????

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题