如何在service层调用 netty 4.x 中的 ctx?

苍之弦 2019-08-30 10:36:05
大家好, 我有一个问题没法解决, 在网上找了很多方法也找不到我想要的那种,
我使用的是

springboot 2.0
netty 4.x

就是我有一个疑问, 当 netty 服务启动后, 且成功向连接的客户端发送信息后, 请问我要怎么在 service 层获取到 ctx?
众所周知 , netty 向客户端发送信息, 使用的是 ctx.writeAndFlush("hello!"); ,那么如果我要在service 层调用这个 ctx, 然后使用
ctx.writeAndFlush(Object); 向客户端发送信息呢? 如果大家有解决方案的话, 还望不吝赐教, 感激不尽

由于netty 服务部分的代码基本上都大同小异, 所以我也就不贴代码了, 因为问题就是上面那个问题 , ^_^
...全文
273 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
苍之弦 2019-08-30
  • 打赏
  • 举报
回复
但是这个方法好像是还有一些问题, 比如那个 clientId 这个变量, 这个变量是中客户端发送到服务器的客户端 ID编号, 用于识别连接到服务端的客户端主机, 有了这个ID, 服务端才知道将这个挑信息发送到哪一个客户端机器上去,,,但是,,我现在没法获取客户端的信息, 因为客户端使用的unity, 而unity使用的是C#, 我在C#中使用的socket, 使用我的Java netty 服务器好像不能获取C#端发送过来的信息, 所以也就没法被动获取客户端的ID编号, 这个ID不是IP, 是自定义的识别编号而已, 还有一个问题, 就是这个缓存是有时间限制的, 如果缓存过了, 而客户端还在连接服务端, 那么就不会触发新的缓存, 那么服务端如果想向客户端发送信息就会变得很困难
苍之弦 2019-08-30
  • 打赏
  • 举报
回复
这是这个问题的解决方法, 我现在把源码贴出来, 新建一个类, 取名 为 CacheHelper

import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
/*
 *@Description //TODO 缓存帮助类$
 *@Author 吾王剑锋所指 吾等心之所向
 *@Date 2019/8/30 11:11
 */
public class CacheHelper{
    private static final Logger LOGGER = LoggerFactory.getLogger(EntityCacheHelp.class);

    public static Cache<Integer, ChannelHandlerContext> channelIdCache = CacheBuilder
                                                                            .newBuilder()
                                                                            .maximumSize(99999)
                                                                            .expireAfterAccess(120, TimeUnit.SECONDS)
                                                                            .build();

    public static boolean arrayEquals(String[] a,String[] b){
        return Arrays.equals(a, b);
    }

    public static String[] getItemVosByIndicex(List<ItemVO> itemVos){
        Set<String> set = new HashSet<>();
        /*itemVos.forEach(itemVo -> set.add(itemVo.getItemInfo()));*/
        return set.toArray(new String[set.size()]);
    }
}
然后, 在netty 服务启动的地方, 例如在 channelActive 方法中使用缓存来保存 ctx

 /**
     * 客户端主动连接服务端 连接成功时向客户端发送一条信息
     *
     * */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("RemoteAddress"+ ctx.channel().remoteAddress() + " active !");
        LOGGER.info("msg send active !"+ctx.channel().writeAndFlush("123456"));
        ctx.writeAndFlush("啦啦啦!");
        CacheHelper.channelIdCache.put(56193,ctx);
        super.channelActive(ctx);
    }
这样, 在建立连接后, 缓存会自动将 ctx 保存起来 如果需要使用 ctx, 就在需要使用的地方

 public Boolean firstSendMsg(int clientId, JSONObject jsonObject){
        try{
            if(jsonObject == null) return false;
            System.out.println(jsonObject);
            ChannelHandlerContext ctx = CacheHelper.channelIdCache.getIfPresent(clientId);
            ctx.writeAndFlush(jsonObject);
        }catch (Exception ex){
            LOGGER.error(ex.getMessage(), ex);
        }
        return true;
    }
啦啦啦,,就是这么简单, 哇, 我好开心啊
苍之弦 2019-08-30
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
可以考虑在你的service类中,增加这个ctx的初始化的处理,在{}中初始化ctx。
你好, 我已经解决这个问题啦,非常感谢你的热心 我的解决方案是: 用缓存机制将 ctx 缓存保存起来, 之后再从缓存里提取出来就行了
oh_Maxy 2019-08-30
  • 打赏
  • 举报
回复
可以考虑在你的service类中,增加这个ctx的初始化的处理,在{}中初始化ctx。
苍之弦 2019-08-30
  • 打赏
  • 举报
回复
引用 7 楼 oh_Maxy 的回复:
嗯,如果是单机系统,也可以用静态常量Map作为缓存。
主要是这已连接, 基本上不会断开, 现在是在测试阶段我使用缓存, 正式版的时候估计我得用数据来保存了, 缓存有点不够安全
oh_Maxy 2019-08-30
  • 打赏
  • 举报
回复
嗯,如果是单机系统,也可以用静态常量Map作为缓存。
苍之弦 2019-08-30
  • 打赏
  • 举报
回复
引用 5 楼 oh_Maxy 的回复:
Redis缓存,可以设置永久有效。
还在研究怎么配置redis, 我的redis是配置在Linux 的 Ubuntu 上的
oh_Maxy 2019-08-30
  • 打赏
  • 举报
回复
Redis缓存,可以设置永久有效。
   本课程由《Netty 4核心原理作者》亲授。    在互联网分布式系统的推动下,Netty 作为一个能够支撑高性能、高并发的底网络通信框架而存在。Netty是基于 Java NIO 实现的,对 NIO 进行了非常多的优化,因此深受广大开发者尤其是一线大厂开发者的青睐。    作为一个 Java 开发者,如果没有研究过 Netty,那么你对 Java 语言的使用和理解可能仅仅停留在表面,会点 SSH,写几个 MVC,访问数据库和缓存,这些只是初级 Java 开发者做的事。如果你要进阶,想了解 Java 服务器的高阶知识,Netty 是一个必须要跨越的门槛。学会了 Netty,你可以实现自己的 HTTP 服务器、FTP 服务器、UDP 服务器、RPC 服务器、WebSocket 服务器、Redis 的 Proxy 服务器、MySQL 的 Proxy 服务器等。    如果你想知道 Nginx 是怎么写出来的,    如果你想知道 Tomcat 和 Jetty 是如何实现的,    如果你也想实现一个简单的 Redis 服务器,    ……    那么你应该好好研究一下 Netty,它们高性能的原理都是类似的。    因为 Netty 5.x 已被官方弃用,本课程内容基于 Netty 4 分析其核心原理,培养高级开发者自己“造轮子”的能力。本课程不仅讲述理论知识,还围绕能够落地的实战场景,开创手写源码的学习方式,使学习源码更加高效。本书的主要特色是首次提供了基于 Netty 手写 RPC 框架、基于 Netty 手写消息推送系统等实战案例。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧