smartroute集成聊天通讯集群

在制定一个规模比较多大的聊天应用时,往往需要制定部署多个应用服务,其一可以保障服务的可靠性,其二可以增加用户负载量.但制定这样一种应用体系是一件复杂的事情,毕竟同一群体的用户实际上会在不同的服务器接入,这样信息转发和处理就是一件比较麻烦的事情.但通过smartroute的订阅机制这一系列的事情都变得简单.

依据客观情况在设计的时候一般都只是功能优先,对于大规模的应用往往是后期扩展.但是基于集群扩展在设计上就需要做得很多工作作和规划.然而使用smartroute则会变得非常简单,因为并不需要在设计和规划上做多余的工作即可实现跨服务器集群交互.也许你感觉这是不太可能的事情,但以下示例会让你感觉到smartroute的智能之处.

  

对于以上场景设计需要考虑的事情比较多除了考虑节点和节点的通讯外,还需要考虑用户所登陆的节点,消息如何路由转发和增加节点需要如何切入集群等复杂技情况.而用smartroute不需要安装任何服务和配置即可自动完成,接下来看下如果使用smartroute来解决一些看去都很复杂的工作.

集群服务端实现

如是一开始上面架构规划设计,那肯定是很复杂的工作,那加入smartroute后的设计到底怎样呢?

private static IServer mServer;

        static void Main(string[] args)
        {

            Route.AddLogHandler(new ConsoleLogHandler(LogType.DEBUG | LogType.ERROR | LogType.FATAL | LogType.INFO | LogType.NONE | LogType.WARN));
            Route.DefaultNode.Open();
            mServer = ServerFactory.CreateTCP();
            mServer.Handler = new Program();
            mServer.Port = 8012;
            mServer.Open();
            System.Threading.Thread.Sleep(-1);
        }

        public void Connect(Beetle.Express.IServer server, Beetle.Express.ChannelConnectEventArgs e)
        {
            TCPSubscribeHandler tcpsub = new TCPSubscribeHandler();
            tcpsub.Channel = e.Channel;
            SmartRoute.Protocol.Packet packet = new SmartRoute.Protocol.Packet();
            packet.Channel = e.Channel;
            packet.Receive = OnMessageReceive;
            e.Channel.Package = packet;
            Route.Subscribe(e.Channel.ID, tcpsub);
        }

        public void Disposed(Beetle.Express.IServer server, Beetle.Express.ChannelEventArgs e)
        {
            Route.UnSubscribe(e.Channel.ID);
            UnRegister ureg = new UnRegister();
            ureg.IP = e.Channel.EndPoint.ToString();
            ureg.Name = e.Channel.Name;
            ureg.SendTo(s => s.Mode(ReceiveMode.NotEq), e.Channel.ID);
        }

        private void OnMessageReceive(object sender, Beetle.Express.PackageReceiveArgs e)
        {
            IMessage message = (IMessage)e.Message;
            switch (message.MessageType)
            {
                case "Register":
                    Register reg = message.GetBody<Register>();
                    e.Channel.Name = reg.Name;
                    reg.IP = e.Channel.EndPoint.ToString();
                    reg.SendTo(s => s.Mode(ReceiveMode.All), e.Channel.ID);
                    break;
                case "Speak":
                    Speak speak = message.GetBody<Speak>();
                    speak.User = new Register();
                    speak.User.Name = e.Channel.Name;
                    speak.User.IP = e.Channel.EndPoint.ToString();
                    speak.SendTo(s => s.Mode(ReceiveMode.NotEq), e.Channel.ID);
                    break;
            }
        }

你没有看错,以上代码就是一个基于集群的简单聊天服务网关,看上去是不是比编写一个普通网络程序的来得更简单多.接下来讲解一下主要代码的作用.

注册订阅

当网关接受到接入的时候会向节点注册一个订阅Route.Subscribe(e.Channel.ID, tcpsub);,而订阅的ID则连接在当前服务的唯一标识,而订阅实现是一个TCP连接订阅.

  取消订阅

当网关接受到断开的时候则取消订阅 Route.UnSubscribe(e.Channel.ID);

发送消息

而当网关接收到消息的情况则把消息投递出去,reg.SendTo(s => s.Mode(ReceiveMode.All), e.Channel.ID)是投递给所有订阅, speak.SendTo(s => s.Mode(ReceiveMode.NotEq), e.Channel.ID)则投递给非当前Channel.ID的所有订阅

智能组建节点集群

如果这个服在当前局域网内只运行一个实例,那它紧紧是一个普通的服务端,但如果节点发现网内还有其他节点在运行的情况下则会去发现对方并组建成通讯集群.当组建集群后每个节点的订阅信息都会同步到不同节点下,每个节点都是相互直连不存在中心服务.当一个节点接收一个消息投递的时候会找相应的订阅,如果是本机订阅则会直接调用订阅;如果是订阅在其他节点则把消息投递到相应的节点,由相应的节点调用订阅.

单节点动行效果

多节点运行效果

一旦节点发现网内有其它节点就会发现组建集群并同步订阅,一集群组建完成后就可以通过节点进行信息交互.

总结

实际上一个聊天服务的功能并不这么简单,往往具备有大厅,群组等等.其实使用smartrote处理这些信息转发则是非常简单的事情.可以针对大厅,群组制定订阅服务节点;然后消息发送到相关订阅,然后再由这些服务查找出具体的订阅用户然后分发即可.所以smartrote的订阅看上去是很简的功能,实现上可以实现很多意想不到的功能,如FTP,HTTP和MQ等等订阅的实现并注册到smartroute中统一集成分发.

下载完整示例代码

时间: 2024-10-16 16:46:07

smartroute集成聊天通讯集群的相关文章

.Net Core开源通讯组件 SmartRoute(服务即集群)

SmartRoute是基于Dotnet Core设计的可运行在linux和windows下的服务通讯组件,其设计理念是去中心化和零配置即可实现服务通讯集群.SmartRoute是通过消息订阅的机制实现服务与服务之间的通讯,它可以让广播网段内所有服务器上的应用自动构建通讯集群: 而通讯集群完全是SmartRoute自动构建并不需要进行任何配置或安装中间服务.通过这种全新的通讯开发方式可以让开发者更轻松和简单地构建基于服务的集群通讯应用. SmartRoute的发展目标   智能集成服务通讯交互 不

Spring集成redis集群

Spring集成redis集群 有密码 Maven <jedis.version>2.9.0</jedis.version> <spring-data-redis.version>1.7.1.RELEASE</spring-data-redis.version> <spring.version>3.2.17.RELEASE</spring.version> <dependency> <groupId>org.s

Android/iOS微信6.3.5同时发布更新 支持群视频聊天、群公告

下午微信6.3.5发布更新,新版最大变化就是支持群视频聊天,又一次向手机QQ靠拢.在群管理方面,支持发布群公告,支持群主转让给其他群成员,同样都是QQ玩剩下的功能.另外,新版支持微信运动查看步数图表.添加关注的人,而在投稿表情里可以给艺术家发红包. 现在群里也可以视频聊天   群主可以发布群公告,可将群主转让给其他群成员   微信运动可以查看步数图表,添加关注的人   投稿表情里可以给艺术家发红包  

Gitlab CI 集成 Kubernetes 集群部署 Spring Boot 项目

在上一篇博客中,我们成功将 Gitlab CI 部署到了 Docker 中去,成功创建了 Gitlab CI Pipline 来执行 CI/CD 任务.那么这篇文章我们更进一步,将它集成到 K8s 集群中去.这个才是我们最终的目标.众所周知,k8s 是目前最火的容器编排项目,很多公司都使用它来构建和管理自己容器集群,可以用来做机器学习训练以及 DevOps 等一系列的事情. 在这里,我们聚焦 CI/CD,针对于 Spring Boot 项目,借助 Gitlab CI 完成流水线的任务配置,最终部

dubbo学习之dubbo管理控制台装配及集成zookeeper集群部署(1)【转】

dubbo管理控制台开源部分主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能. 1.下载dubbo 地址:http://code.alibabatech.com/mvn/releases/com/alibaba/dubbo-admin/2.4.1/dubbo-admin-2.4.1.war 本人将tomcat安装在/opt/目录下,先删除tomcat/webapps下自带的ROOT文件夹,将下载的war包解压到webapps/ROOT,命令如下: [plain] 

HBase集成Zookeeper集群部署

大数据集群为了保证故障转移,一般通过zookeeper来整体协调管理,当节点数大于等于6个时推荐使用,接下来描述一下Hbase集群部署在zookeeper上的过程: 安装Hbase之前首先系统应该做通用的集群环境准备工作,这些是必须的: 1.集群中主机名必须正确配置,最好有实际意义:并且主机名都在hosts文件中对应主机IP,一一对应,不可缺少 这里集群有6台服务器:bigdata1,bigdata2,bigdata3,bigdata4,bigdata5,bigdata6 这里是3台主机,分别对

Springboot2.X集成redis集群(Lettuce)连接

前提:搭建好redis集群环境,搭建方式请看:https://www.cnblogs.com/xymBlog/p/9300574.html 1. 新建工程,pom.xml文件中添加redis支持 <dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-data-redis</artifactId></depend

Springboot集成Quartz集群

为什么要使用Quzrtz集群 在项目进行集群部署时,如果业务在执行中存在互斥关系,没有对定时任务进行统一管理,就会引起业务的多次执行,不能满足业务要求.这时就需要对任务进行管理,要保证一笔业务在所有的集群环境中,有且只有一台机器能执行该任务. 如果不适用Quartz集群,要如何实现这种业务逻辑? 在这里只列出两种简单的思路: 利用单线程机制.可以在redis中设置一个属性为空,每次任务执行时去设置这个全局变量,进入任务中需要对值进行校验,值不为空则跳过本次执行任务,值为空时进行设置,方法执行完毕

SpingBoot之集成Redis集群

一.安装Redis集群 安装步骤参照网上教程,Mac安装步骤参照https://github.com/muyl/mac-docker-redis-cluster 二.创建SpringBoot工程 创建Redis配置类 package com.example.chapterredis.common.config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.slf4j.Logger; import