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. 必须掌握的Linux命令

    章节简述: 本章节讲述系统内核.Bash解释器的关系与作用,教给读者如何正确的执行Linux命令以及常见排错方法. 经验丰富的运维人员可以恰当的组合命令与参数,使Linux字符命令更加的灵活且相对减少 ...

  2. 解决vs2013下创建的python文件,到其他平台(如linux)下中文乱码(或运行时报SyntaxError: (unicode error) 'utf-8' codec can't decode byte...)

    Vs2013中创建python文件,在文件中没输入中文时,编码为utf-8的,如图 接着,在里面输入几行中文后,再次用notepad++查看其编码如下,在vs下运行也报错(用cmd运行就不会): 根据 ...

  3. NGUI中的Tween的委托使用

    public TweenPosition tweenIn; public TweenScale tweenOut; EventDelegate In = new EventDelegate(this, ...

  4. rocketmq(1)

    参考: 开源社区:https://github.com/alibaba/RocketMQ rocketmq入门: http://www.cnblogs.com/LifeOnCode/p/4805953 ...

  5. C# 语言规范_版本5.0 (第16章 异常)

    1. 异常 C# 中的异常用于处理系统级和应用程序级的错误状态,它是一种结构化的.统一的和类型安全的处理机制.C# 中的异常机制非常类似于 C++ 的异常机制,但是有一些重要的区别: 在 C# 中,所 ...

  6. php获取url字符串截取路径的文件名和扩展名

    <?php //获取连接里边的id $url = 'http://www.rong123.com/cjbkscbsd/x_dfsdfs/24454_1_1.html'; function get ...

  7. Pelican搭建静态博客

    前言 一直以来都希望拥有属于自己的个人博客,随性发点信息,写点技术感想,记录自己的生活,重要的是不受广告的影响.不被河蟹.不会担心有一天被莫名其妙地消失. 之前看过一篇文章:"像黑客一样写博 ...

  8. JavaScript中时间戳和时间的相互转换

    时间转换成时间戳: var time = new Date(); var timestamp=Date.parse(time)   //毫秒数,得到秒除以1000: 时间戳转成时间: 1.转换成 20 ...

  9. Myeclipse10、Maven构建Javaweb项目

    主要介绍如何使用 Myeclipse 10 构建 Maven Web 项目,关于 Maven 的介绍就略过了. 工具/原料   myeclipse apache-maven-3.1.0 方法/步骤   ...

  10. 2016 ACM Amman Collegiate Programming Contest D Rectangles

    Rectangles time limit per test 5 seconds memory limit per test 256 megabytes input standard input ou ...