Chinaunix首页 | 论坛 | 博客
  • 博客访问: 476237
  • 博文数量: 55
  • 博客积分: 1867
  • 博客等级: 上尉
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-29 01:33
文章分类

全部博文(55)

文章存档

2013年(1)

2012年(2)

2011年(16)

2010年(11)

2009年(5)

2008年(10)

2007年(8)

2006年(2)

分类: 系统运维

2011-02-01 17:56:05


三、 数据结构

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);
未完待续...
阅读(2302) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~