【netty-socketio】@OnEvent作用

下面主要讲解跟 @OnEvent 相关代码的注释

一:SocketIoServer创建

启动服务端,首先要创建SocketIoServer,创建socketIoServer实例时做了如下几件事:

  1. 创建namespacesHub = new NamespacesHub(读取到的配置#{com.corundumstudio.socketio}),存放创建的所有的Namespace
  2. 创建并添加默认mainNamespace<“”,mainNamespace>到namespacesHub.namespaces中,mainNamespace默认名为空“”
  3. 创建mainNamespace时创建了ScannerEngine engine = new ScannerEngine() ,主要负责找到注解对应的AnnotationScanner
  4. 创建engine时创建了3个AnnotationScanner并放到了全局变量 annotations 中,用于定义扫描哪些注解,以及扫描到这些注解后要添加哪些监听,及调用到被这些注解标注的方法时要做的事情
private static final List<? extends AnnotationScanner> annotations=
 Arrays.asList(new OnConnectScanner(), new OnDisconnectScanner(), new OnEventScanner());

二:SpringAnnotationScanner 注解扫描器

其实SpringAnnotationScanner实现了BeanPostProcessor,定义了三个要处理的注解

private final List<Class<? extends Annotation>> annotations =
      Arrays.asList(OnConnect.class, OnDisconnect.class, OnEvent.class);
  1. 前置处理器: 判断要创建的bean中的方法是否有annotations 中定义的注解,有则赋值此类给originalBeanClass
  2. 后置处理器: 判断originalBeanClass是否为null,不为null,说明此类在前置处理器中判断此类中有方法有annotations中的注解 ,则
    a. 向上面创建的socketIoServer实例中添加监听:socketIOServer.addListeners(bean, originalBeanClass);
    b. 将originalBeanClass置为null

三:SocketIoServer

  1. socketIdServer.addListeners(Object listeners, Class<?> listenersClass) 添加注解对应的监听

    a. 调用mainNamespace.addListeners(listeners, listenersClass),啥也没做,直接调用scannerEngine.scan
    b. 调用scannerEngine.scan(Namespace namespace, Object object, Class<?> clazz)
      I. 获取此类中声明的方法,若这些方法标有annotations中对应的注解,则调用该注解对应的注解扫描器AnnotationScanner的下面两个方法,
      II. annotationScanner.validate:校验方法入参进行校验,如OnEventScanner.validate
      III. annotationScanner.addListener:向对应的注解扫面器annotationScanner添加监听,如OnEventScanner.addListener,当该注解标注的方法被调用时,就会回调添加监听者的onData方法进行对应的逻辑处理

四:OnEventScanner

  1. validate(Method method, Class<?> clazz):参数个数校验
    a. 获取方法参数列表参数个数paramsCount
    b. 获取方法中SocketIOClient和AckRequest类型的参数在参数列表中的个数socketIOClientIndex
    c. 获取方法中AckRequest类型的参数在参数列表中的个数ackRequestIndex
    d. 获取方法中除SocketIOClient和AckRequest类型所有真正业务用来传输数据的所有参数在参数列表中个数dataIndexes.size()
    e. 判断paramsCount是否等于socketIOClientIndex+ackRequestIndex+dataIndexes.size()
  2. addListener(Namespace namespace, final Object object, final Method method, Annotation annot)
    a. 调用namesapce.addEventListener(eventName, eventClass, listener)

五:Namespace

private final ScannerEngine engine = new ScannerEngine();
private final ConcurrentMap<String, EventEntry<?>> eventListeners = PlatformDependent.newConcurrentHashMap();

  1. addListeners(Object listeners, Class<?> listenersClass)
    a. 只调用了下engine.scan(this, listeners, listenersClass);
  2. addMultiTypeEventListener(String eventName, MultiTypeEventListener listener,
    Class<?>… eventClass)真正给事件添加了监听者

    a. 创建EventEntry<“#{方法@OnEvent对应的value},entry”>并存入eventListeners
    b. 向entry添加监听者DataListener类型的OnEventScanner,实现onData方法,方法作用:
      I. 获取方法所有参数存入args
      II. 通过反射真正执行被注解标注的方法method.invoke(object, args)

六: EventEntry

private final Queue<DataListener<T>> listeners = new ConcurrentLinkedQueue<DataListener<T>>();;
  1. addListener(DataListener listener):将DataListener监听保存到listeners

以上都是启动Bean出事后完成的工作,下面就是建立连接后通过channel传输数据时的逻辑了


当前端发送数据到channel时,最终会走到pipeline中的InPacketHandler节点,从而走到channelRead0,从而调用 PacketListener.onPacket(Packet packet, NamespaceClient client, Transport transport) ,若type=Message;subType=PacketType.ACK,接着调用Namespace.onEvent(NamespaceClient client, String eventName, List<Object> args, AckRequest ackRequest),下面着重看一下Namespace.onEvent做了哪些事情:

七: Namespace.onEvent(NamespaceClient client, String eventName, List args, AckRequest ackRequest)

  1. 首先根据eventName获取eventListeners中对应的EntryEntry从而获取对应的所有监听DataListener
  2. 回调所有监听的onData,执行真正的监听逻辑,在onData里面通过反射调用了真正的方法

整体流程

在这里插入图片描述

大致逻辑: 服务端启动初始化bean时,利用SpringAnnotationScanner 的前后置处理器,找到@OnEvent注解,并将其key为@OnEvent设置的value,value为监听包装成的EventEntry保存到Namespace的eventListeners中 private final ConcurrentMap<String, EventEntry<?>> eventListeners = PlatformDependent.newConcurrentHashMap()中,当有数据写入cannel中,服务端在读取channel中的数据时,获取对应namespace的所有监听eventListeners,并找到key为指定事件名的所有监听,并调用监听的onData方法,onData作为对应的逻辑处理后通过反射调用注解锁标注的方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty-socketio是一个用于构建实时通信应用程序的开源框架。它基于Netty框架,通过使用WebSocket协议来实现异步、高性能的网络通信。Netty-socketio具有以下特点: 1. 强大的异步处理能力:Netty-socketio采用事件驱动的方式处理客户端请求,能够高效地处理大量并发连接。 2. 完善的消息传递机制:Netty-socketio提供了灵活的消息传递方式,支持广播、点对点、房间等不同的消息发送方式,满足不同场景下的通信需求。 3. 多协议支持:Netty-socketio不仅支持WebSocket协议,还支持其他常用的协议,如TCP、HTTP等,便于与现有的系统集成。 4. 可扩展性强:Netty-socketio提供了丰富的拓展接口,用户可以根据自己的需求定制和扩展框架的功能。 5. 易于使用:Netty-socketio提供了简洁的API和丰富的文档,可以快速上手使用,并提供了相应的示例代码,方便开发者学习和理解。 对于客服应用来说,Netty-socketio作为一个实时通信框架,可以用于构建在线客服聊天系统。通过使用Netty-socketio,我们可以实现客户与客服人员之间的实时消息传递,支持文字、图片、文件等多种类型的消息。客户可以通过网页或移动端应用与客服人员进行沟通,实时解决问题,提升用户体验。 Netty-socketio提供了强大的异步处理能力和全双工通信机制,能够处理大量并发连接,并保持连接的稳定性和可靠性。同时,它的多协议支持和可扩展性强的特点,使得我们可以根据自己的业务需求进行定制和拓展,满足不同客服场景下的通信需求。 总之,Netty-socketio作为一个强大的实时通信框架,为客服应用提供了一种高效、稳定的解决方案,帮助企业构建更好的客服系统,并提升客户的满意度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值