其实我们整个封装的核心,其实就两个部分。
这个交换机,其实就是我们的消息的发送者。我们这里其实主要有两个模式:
之所以要使用这个交换机只不过是为了方便做管理罢了。因为在我的社区当中有个类似于聊天室的功能,而且这个聊天室有很多个。因此需要进行简单管理。再或者说有时候我们有多个不同类别的设备需要进行管理互通之类的,例如电脑给手机发送消息。但是不管怎么说,最基本的其实就是这两个,也就是:组内广播,一对一点播(组内,组外)
此外,交换机的匹配规则是可以自定义的,有时候,可能需要匹配到以A开头的组别,等等,这个后面都好说。
说到这里的话,你应该很好奇,这个玩意该怎么实现。其实很简单,首先我们对所有的用户的连接给管理起来,把对应的userid-group和channel放到一个map当中管理起来。然后,我们再建立一个分组索引即可。这个分组索引当然也是一个map来进行维护的。这里主要有两个:
我们这里面定义的处理器,其实和netty里面定义的处理器是一样的,其目的都是为了方便实现对消息的处理。刚刚的交换机实现了,这个消息要发到那里去。那么现在的处理器决定了,这个消息要怎么处理才能发送。大白话就是交换机决定了你的消息能到谁的手上,处理器决定了你的消息长啥样
那么这里有什么重要点嘛?其实就两个:
那么实现了这两个点,我们handler就基本上可以愉快玩耍了。
当然在这里我们这里先讨论的是关于这个Netty本身,先把这个主体玩意搭建起来,后面的增强就很好处理了。
其实使用netty就这几步:
我们先来看到配置:
同时在这里你应该注意到了,我们在这里还需要对消息进行一个转化,这里首先是定义了一个基本的消息类:
packagecom.huterox.messaging.core.entities;/***netty客户端返回数据格式**/publicclassDataContent{//用户idprivateStringuserid;//用户组别privateStringgroup;//此次用户请求的行为privateIntegeraction;//携带的消息(这里是一个object对象,做强制类型转换即可)privateObjectmessage;publicDataContent(Stringuserid,Stringgroup,Integeraction){this.userid=userid;this.group=group;this.action=action;}publicStringgetUserid(){returnuserid;}publicvoidsetUserid(Stringuserid){this.userid=userid;}publicStringgetGroup(){returngroup;}publicvoidsetGroup(Stringgroup){this.group=group;}publicIntegergetAction(){returnaction;}publicvoidsetAction(Integeraction){this.action=action;}@OverridepublicStringtoString(){return"DataContent{"+"userid='"+userid+'\''+",group='"+group+'\''+",action="+action+'}';}}然后的话,我们有个JsonUtils可以帮助我们把这些东西转化未我们的Java对象。
packagecom.huterox.messaging;importcom.huterox.messaging.config.NettyProperties;importio.netty.bootstrap.ServerBootstrap;importio.netty.channel.nio.NioEventLoopGroup;importjavax.annotation.Resource;/***服务器启动类*/publicclassServerBoot{@ResourceServerBootstrapserverBootstrap;@ResourceNioEventLoopGroupboosGroup;@ResourceNioEventLoopGroupworkerGroup;/***开机启动*/publicvoidstart()throwsInterruptedException{//绑定端口启动serverBootstrap.bind(NettyProperties.port).sync();}/***关闭线程池*/publicvoidclose()throwsInterruptedException{boosGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}后面我们在SpringBoot当中启动的时候,指定启动start()即可。这里面怎么具体操作的话,需要在后面具体使用的时候再进行说明了,届时会再给出前端的连接代码。