ESFramework 4.0 进阶(04)-- 驱动力:通信引擎(下)一文末尾我们已经将通信引擎以及整个消息骨架流程组装起来了,只要通信引擎一接收到消息,框架就会按照规定的流程进行运转。到这里,自然想到一个问题,如何来发送消息了?没有发送,何谈接收,就更不会有后续的驱动整个消息处理的骨架流程了。

一.发送消息时遇到的问题

ESFramework 4.0 进阶(03)-- 驱动力:通信引擎(上)一文中学习引擎接口时,我们知道,各种引擎都提供了发送消息的方法,向服务端引擎IServerEngine的SendMessageToClient方法和PostMessageToClient方法,以及客户端引擎IPassiveEngine的SendMessageToServer方法。我们可以直接调用它们来发送构造好的消息,但是可能会引发两个问题:

(1)由于我们的消息加密、压缩等环节都位于MessagePipe的MessageTransformer组件中,如果直接调用通信引擎发送消息,则该消息不会参与这些变换。

(2)同样的,这些被直接发送的消息也不会被InnerMessageSpy和GatewayMessageSpy监控到。

  也就是说,使用通信引擎直接发送消息时,就绕过了MessagePipe,也就破坏了ESFramework规定好的骨架流程,这可能会导致一些严重的后果。比如,在某个项目中,我们挂接了一个InnerMessageSpy,原本期望是拦截所有发送出去的“明文”消息,结果却有一些漏网之鱼;原本我们期望所有的消息都是经过MessageTransformer加密后再发送,结果有些消息以明文的形式发送到了网络上。

怎么办了?使用正规消息发送器IRegularSender,所谓“正规”的意思,就是它会保证消息在被通信引擎发送到网络之前,必须经过MessagePipe。

二.正规消息发送器

我们可以通过以下经过增强的骨架流程图来更清楚地展示IRegularSender在骨架流程中的作用:     

IRegularSender在NakeDispatcher与MessagePipe之间切入,将要发送的消息传递给MessagePipe,正如NakeDispatcher将消息处理器返回的消息传递给MessagePipe一样。这样就保证了所有的消息的发送都是完全一致的,且都遵守了ESFramework规定的流程。

你也许会说,如果有些类型消息不是很重要,我不想经过MessageTransformer来加密它们以节约CPU时间,那该怎么办了?其实很容易,首先MessgePipe和MessageTransformer是必须经过的,但是你可以在MessageTransformer中配置某些消息类型,只要MessageTransformer遇到这些类型的消息,就不对起做任何变换,直接返回原始消息即可。ESFramework.Core.BaseMessageTransformer抽象类就为你内置了这一功能,你的MessageTransformer只要从其继承即可。这样一来,就既解决了问题,又保证了骨架流程不被破坏。

三.服务端正规消息发送器

服务端正规消息发送器接口ESFramework.Server.IRegularSender以及其实现类ESFramework.Server.RegularSender,用于保证服务端给客户端发送的消息遵守ESFramework骨架流程。我们来看看ESFramework.Server.RegularSender的类图:

(1)RegularSender有两个public重载的方法,用于将消息发送或投递给N个用户,通过参数UserID指明要将消息发送的目的对象。而我们知道,通过IServerEngine发送消息时,其接收的参数是用户地址UserAddress,所以RegularSender必须借助于用户管理器IUserManager,以根据UserID获取其对应的UserAddress。

(2)RegularSender依赖于MessagePipe就很容易理解了,正是要让消息经过MessagePipe才能算是保证了骨架流程。

(3)RegularSender还提供了一个protected的virtual方法SendMessageToForeigner,这个方法默认实现是什么事情都不做:

    protected virtual void SendMessageToForeigner(IMessage msg, string userID)
    {
    } 

这个方法有什么用了?它被用于ESPlatform,当有很多台应用服务器做Cluster时,某个需要接收该消息的在线用户可能是位于另外一台服务器上,那么,在ESPlatform中,我们只要override这个方法,就可以实现跨应用服务器的消息发送。具体细节我们将在详细介绍ESPlatform时讨论。

通过下面的代码,我们来实例化一个服务端的正规消息发送器实例:


    IServerEngine serverEngine = ......;
    IMessagePipe messagePipe = ......;
    IUserManager userManager = ......;
    RegularSender regularSender = new RegularSender();
    regularSender.MessagePipe = messagePipe;
    regularSender.UserManager = userManager;
    regularSender.ServerEngine = serverEngine;
    //发送消息
    IMessage message = null ;
    regularSender.SendMessage(message, "aa01");

  关于如何构造服务端引擎实例、用户管理器实例以及消息管道实例,可以参见《ESFramework 4.0 进阶》系列的前面几篇文章。

四.客户端正规消息发送器

服务端正规消息发送器接口ESFramework.Passive.IRegularSender以及其实现类ESFramework.Passive.RegularSender,用于保证客户端提交给服务器的消息都遵守ESFramework骨架流程。我们来看看ESFramework.Passive.RegularSender的类图:

客户端的RegularSender相对更简单一些,消息始终是被提交到服务器,即使是P2P消息,也是通过服务器来中转(关于通过P2P Channel发送P2P消息,我们将通过后面即将介绍的MessageTransceiver来解决)。

最后,我们来构造一个客户端正规消息发送器实例:


    IPassiveEngine passiveEngine = ......;
    IMessagePipe messagePipe = ......;    
    RegularSender regularSender = new RegularSender();
    regularSender.MessagePipe = messagePipe;   
    regularSender.PassiveEngine = passiveEngine;
    //发送消息到服务器
    IMessage message = null ;
    regularSender.SendMessage(message, DataPriority.Common);

  好了,正规消息发送器就介绍完毕了。通常,在服务端发送消息都是使用RegularSender,但是在客户端开发时却很少直接使用它,替而代之的是使用IServerAgent和IMessageTransceiver,IServerAgent是ESFramework给出的消息同步调用方案,而IMessageTransceiver则向使用者屏蔽了在发送P2P消息时,是使用的P2P Channel直接发送的还是经过服务器中转的。接下来的文章中,我们就来一个个介绍它们。敬请关注,谢谢。

正规消息发送器-- ESFramework 4.0 进阶(06)的更多相关文章

  1. 消息同步调用-- ESFramework 4.0 进阶(07)

    分布式系统的构建一般有两种模式,一是基于消息(如Tcp,http等),一是基于方法调用(如RPC.WebService.Remoting).深入想一想,它们其实是一回事.如果你了解过.NET的Prox ...

  2. ESFramework 4.0 进阶(04)-- 驱动力:通信引擎(下)

    在ESFramework 4.0 进阶(03)-- 驱动力:通信引擎(上)一文中,我们对ESFramework提供的每一个通信引擎的接口都做了详细了说明,这篇文章我们将继续探讨这些接口的实现类 -- ...

  3. 驱动力—— 通信引擎(上)—— ESFramework 4.0 进阶(03)

    在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中我们详细介绍了ESFramework中消息处理的骨架流程,并且我们已经知道,ESFramework中的所有通信引擎使用 ...

  4. 好友与组--ESFramework 4.0 进阶(11)

    大部分分布式通信系统中,都会涉及到客户端之间相互通信.以及需要将客户端进行分组的功能,或者是类似这方面的需求.ESFramework对这一常见的任务内置了强大的支持,包括从客户端到服务端.一直到Pla ...

  5. 垂直分割群集模型与多通道引擎 -- ESFramework 4.0 进阶(10)

    在ESFramework 4.0 进阶(09)-- ESPlatform 支持的三种群集模型一文中,我们介绍了ESPlatform支持的三种群集模型 -- 垂直分割模型.水平分割模型.交叉模型.我们看 ...

  6. 挂接P2P通道-- ESFramework 4.0 进阶(08)

    最新版本的ESFramework/ESPlus提供了基于TCP和UDP的P2P通道,而无论我们是使用基于TCP的P2P通道,还是使用基于UDP的P2P通道,ESPlus保证所有的P2P通信都是可靠的. ...

  7. 在线用户管理--ESFramework 4.0 进阶(05)

    无论我们采用何种通信框架来构建我们的分布式系统,在服务端进行用户管理都是非常重要的一个环节.然而用户管理是否应该隶属于通信框架了?这个并不一定,通常来说,用户管理是与具体应用紧密相关的,应该是由应用解 ...

  8. 核心梳理——消息处理的骨架流程——ESFramework 4.0 进阶(02)

    在ESFramework 4.0 概述一文中,我们提到ESFramework.dll作为通信框架的核心,定义了消息处理的骨架流程,本文我们来详细剖析这个流程以及该骨架中所涉及的各个组件.ESFrame ...

  9. ESFramework 4.0 进阶(01)-- 消息

    需要交互的分布式系统之间通过消息来传递有意义的信息.消息是通信框架的核心.离开了消息,再谈通信框架就没有任何意义,所以,消息是ESFramework中一个最核心的概念. 一. 消息的类别 在具体的应用 ...

随机推荐

  1. 利用VR技术,走进白宫,走进奥巴马

    奥马巴卸任演讲由诺基亚OZO全程360° VR直播,并不是每个人都能去白宫拜访,一窥白宫内部的模样,更不可能有多少人有机会在奥马巴面前听他讲讲他的家.   现在前任总统巴拉克奥巴马以及其夫人米歇尔奥巴 ...

  2. JavaScript简单的一些....

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. DuiLib 中滚动条不显示的问题

    DuiLib 很好用,同时在没有完全理解源码的前提下,坑也不少,比如今天遇到的添加滚动条不显示... 情况是这样的,将一个页面作为Tab控件的其中一页,为了代码不窝在一起,就没有在CreateCont ...

  4. linuxlab下虚拟板与主机通信

  5. db2 常用配置

    db2set配置: db2set DB2_ENABLE_LDAP=NO db2set DB2_ALTERNATE_GROUP_LOOKUP=GETGROUPLIST db2set DB2_RESTOR ...

  6. IIS 支持 ajax 跨域

    第一,首先要浏览器支持. Firefox和Chrome都支持了. IE10 也支持. IE8,9 需要使用其他方式才能支持 第二, 加上HTTP header. IIS 7 的方式比较容易. 就在we ...

  7. C# 语言规范_版本5.0 (第14章 枚举)

    1. 枚举 枚举类型 (enum type) 是一种独特的值类型(第 4.1 节),它用于声明一组命名的常量. 下面的示例 enum Color { Red, Green, Blue } 声明一个名为 ...

  8. CSS display:inline-block的元素特点:

    将对象呈递为内联对象,但是对象的内容作为块对象呈递.旁边的内联对象会被呈递在同一行内,允许空格. 在CSS中,块级对象元素会单独占一行显示,多个block元素会各自新起一行,并且可以设置width,h ...

  9. 前端环境安装(node.js+npm+grunt+bower)

    前端开发环境安装(本教程不带开发工具的安装教程,只是环境安装) 本人机器环境win7 64位. 一.node.js安装 进入官网下载node.js文件,http://www.nodejs.org/ 2 ...

  10. 小demo--横向+展开菜单,支持m站

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...