免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1257 | 回复: 0

JavaScript对象间基于Message的同步/异步通信(二) [复制链接]

论坛徽章:
0
发表于 2011-12-19 14:02 |显示全部楼层

三、 数据结构

1、 Message的格式

     Messenger系统里最重要的数据结构自然是message本身。一直在考虑是否有必要为Message定义一个接口,后来觉得也许用数组性能会更好,所以就直接使用一个数组来定义message的格式了。考虑到一般情况的应用,这个 msg 数组包含5个元素,即 msg[0] 至 msg[4], 如图:

具体的字段定义为:

     1. msg[0]: Priority, 数值类型, 调度系统会优先调度紧急消息,仅当没有紧急消息时,调度普通消息,工作于 post 模式,取值范围(0,1), 0 表示紧急, 1 表示普通。

     2. msg[1]: Device, 字串类型, 窗口标识,Messenger系统支持在弹出窗口以及iframe的对象间的通信,本字段表示消息接收者位于哪个窗口或iframe。默认为 null,表示本窗口。

     3. msg[2]: [Recvs...], 数组类型, 消息接收者的id数组,消息发送者可以指定消息被某一个或某几个特定的接收者接收。默认为 null,表示所有订阅该消息的接收者都可以接收。

     4. msg[3]: MsgID, 字串类型, 消息种类的id, 对应 what。

     5. msg[4]: MsgData, 任意类型, 消息的内容, 是通信双方希望传递的实际内容,由通信双方约定具体类型。

2、 Registry的结构

    Messenger是一个基于订阅/发布模式(subscribe/publish)的实现,自然要维护一个订阅者的数据库, 当然在具体的设计和实现中,不会也不必引入数据库的概念,但如下的一个起码的数据表是必需的。 
         

  这样的一张表,在实现中,可以用下图的数据结构来具体实现:



    在JavaScript,可以非常容易地实现上图:

  1.         /**
  2.          * Define the EventQueue class based on subscribe/publish mode
  3.          */
  4.         js.awt.EventQueue = function(){
  5.             /**
  6.              * Registry of subscribtion
  7.              *
  8.              * key is "what"
  9.              * value is a list of the pair (who, where)
  10.              */
  11.              var R = {};
  12.              
  13.             /**
  14.              * Subscribe a message from EventQueue
  15.              *
  16.              * @param what, the message id
  17.              * @param who, the message listener
  18.              * @param where, the message handler
  19.              */
  20.              this.register = function(what, who, where){
  21.                  var recvs = R[what];
  22.                  if(recvs == null){
  23.                      recvs = [];
  24.                      R[what] = recvs;
  25.                  }

  26.                  recvs.push({listener:who, handler:where});

  27.              };
  28.         
  29.         }.$extend(ls.lang.Object);

3、 Message队列的结构

    这个Messenger系统最大的特点是支持异步消息递送,即消息发送者调用post来发送消息。 所谓异步消息递送分为两个阶段, 第一阶段,消息发送者调用post方法,消息直接进入Messenger里的一个队列中,post方法立即返回。 第二阶段, Messenger的调度系统从消息队列中取出一条消息分发给所有订阅者。 
   考虑到可能会有消息优先级的应用需求,在这个Messenger系统里,采用一个简单的方案来实现所谓的优先级队列,即双队列,一个放紧急消息,一个放普通消息。post消息时,根据消息优先级放入不同的队列,当调度系统分发消息时,仅当紧急队列为空,才分发普通队列的消息。 


    在JavaScript里实现这样的一个队列,可以是异常的简单。

  1.         /**
  2.          * Define the EventQueue class based on subscribe/publish mode
  3.          */
  4.         js.awt.EventQueue = function(){
  5.             /**
  6.              * Message queue
  7.              *
  8.              * Q[0] for urgent message
  9.              * Q[1] for general message
  10.              */
  11.              var Q = [[],[]];

  12.              var _get = function(){
  13.                  var msg = Q[0].shift();
  14.                  msg = (msg == undefined) ? Q[1].shift() : msg;
  15.                  return msg;
  16.              };

  17.              var _put = function(msg){
  18.                  Q[msg[0]].push(msg);
  19.              };

  20.              /**
  21.               * Test whether the message queue is empty
  22.               */
  23.              this.isEmpty = function(){
  24.                  return (Q[0].length + Q[1].length) === 0;
  25.              };

  26.             /**
  27.              * Message sender use this method to post a message and
  28.              * return immediately
  29.              *
  30.              * @param msg
  31.              * +----------+----------+------------+----------+-------------+
  32.              * | PRI     | Device | [recvs..] | msgId | msgData |
  33.              * +----------+----------+------------+----------+-------------+
  34.              */
  35.             this.post = function(msg){
  36.                 _put(msg);
  37.             };

  38.             /**
  39.              * Schedule system use this method to dispatch a message to
  40.              * listeners
  41.              *
  42.              */
  43.             this.dispatch = function(){
  44.                 var msg = _get(), ex;
  45.                 if(msg == undefined) return;

  46.                 // TODO:
  47.                 
  48.             };
  49.             
  50.         
  51.         }.$extend(ls.lang.Object);
未完待续...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP