在制定一个规模比较多大的聊天应用时,往往需要制定部署多个应用服务,其一可以保障服务的可靠性,其二可以增加用户负载量.但制定这样一种应用体系是一件复杂的事情,毕竟同一群体的用户实际上会在不同的服务器接入,这样信息转发和处理就是一件比较麻烦的事情.但通过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中统一集成分发.

下载完整示例代码

smartroute简单集成集群聊天通讯的更多相关文章

  1. SpringBoot学习笔记(13)----使用Spring Session+redis实现一个简单的集群

    session集群的解决方案: 1.扩展指定server 利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略.缺点:耦合Tomcat/ ...

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

    SmartRoute是基于Dotnet Core设计的可运行在linux和windows下的服务通讯组件,其设计理念是去中心化和零配置即可实现服务通讯集群.SmartRoute是通过消息订阅的机制实现 ...

  3. 【Quartz】配置最简单的集群

    在许多情况,我们希望我们的定时任务是可靠的,不会因系统故障.机器宕机而导致某一笔定时任务不能按时运行.这种情况下,我们就需要为Quartz做个集群. 最简单的情况,有两台机器或两个应用,同时维护一批定 ...

  4. redis单机安装以及简单redis集群搭建

    安装环境: 两台虚拟机都是Centos 7.0 IP分别为:192.168.149.132  192.168.149.133 Redis采用的版本是redis-3.2.4 集群是采用两台虚拟机模拟8个 ...

  5. 简单Hadoop集群环境搭建

    最近大数据课程需要我们熟悉分布式环境,每组分配了四台服务器,正好熟悉一下hadoop相关的操作. 注:以下带有(master)字样为只需在master机器进行,(ALL)则表示需要在所有master和 ...

  6. Spring Cloud Hystrix理解与实践(一):搭建简单监控集群

    前言 在分布式架构中,所谓的断路器模式是指当某个服务发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,这样就不会使得线程因调用故障服务被长时间占用不释放,避免故障的继续蔓延.Spring ...

  7. 基于docker-compose部署 简单nsq 集群

    主要目的是搭建一个测试环境,同时使用了nodejs 客户端sdk nsq 简单了解 nsqd:一个负责接收.排队.转发消息到客户端的守护进程 nsqlookupd:管理拓扑信息并提供最终一致性的发现服 ...

  8. 用python实现一个简单的socket网络聊天通讯 (Linux --py2.7平台与windows--py3.6平台)

    windows   --> windows 写法均在py3.6 客户端写法 import socket client = socket.socket() client.connect(('192 ...

  9. [开源精品] C#.NET im 聊天通讯架构设计 -- FreeIM 支持集群、职责分明、高性能

    FreeIM 是什么? FreeIM 使用 websocket 协议实现简易.高性能(单机支持5万+连接).集群即时通讯组件,支持点对点通讯.群聊通讯.上线下线事件消息等众多实用性功能. ImCore ...

随机推荐

  1. Zabbix(一)--zabbix 2.4.8 安装

    zabbix依赖于LAMP,所以部署前要先保证这个平台. 安装服务端(Server) zabbix官网的rpm包都是按照功能分开一个个,比如: zabbix-server-2.4.7-1.el7.x8 ...

  2. NSURLSession的基本使用

    一.简单说明 在iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection完成网路请求相关操作. NSURLSession ...

  3. asp.net(C#) Excel导出类 导出.xls文件

    ---恢复内容开始--- using Microsoft.Office.Interop.Excel; 针对office 2003需添加引用Microsoft   Excel   11.0   Obje ...

  4. js原生实现选项卡功能

    选项卡在js中是一个重要的知识点.他没有那么难,但在工作中却有重要的位置.几乎在每一个网站都能看到选项卡的实例.所以今天写一下选项卡的实现. 我们设想有三个按钮分别来控制三个盒子当我们点击当前的按钮的 ...

  5. android studio 华为手机看不到具体的错误日志

    手机的开发人员选项打开了么,其中的 USB 调试打开了么?搞定他们并重新运行,是否能找到我们的日志?否,转到 2. 日志中是否有这样 could not disable core file gener ...

  6. 计算机网路之动态NAT配置

    配置路由端口的ip地址与打开(省略) 配置路由协议 router eigrp 100 network 211.1.1.0(网络号) 0.0.0.255(通配子掩) network 192.168.1. ...

  7. apache安装mod_deflate配置支持gzip

    apache 配置支持gzip apache使用gzip压缩能够大幅提高网站访问速度并节省网络流量,在网页响应头信息中可以判断是否支持压缩. HTTP/1.1 200 OK Date: Wed, 14 ...

  8. viewpage 循环滑动播放图片

    一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...

  9. Python Charts库的使用

    博客园格式不太好看,可以去本人CSDN博客 http://blog.csdn.net/ashic/article/details/52598664 http://nbviewer.jupyter.or ...

  10. C# Exception 写入文件

    /// <summary> /// 将异常打印到LOG文件 /// </summary> /// <param name="ex">异常< ...