消息创建过程

    本文转载自:Spark & Shine 

网址  http://sparkandshine.net/?p=389

1.消息事件产生器(MessageEventGenerator

    1.1 基本信息

消息事件产生器根据参数产生消息创建事件,进而创建消息。MessageEventGenerator派生出3种新的消息产生器,即OneToEachMessageGenerator、OneFromEachMessageGenerator、MessageBurstGenerator。其类图如下

wKiom1UVU_6ghDnuAAHraUxbDXk597.jpg

   1.2加入事件队列

在创建消息之前,我们会用到实例来管理所有的事件,因此我们需要在正是创建消息前创建实例。

The ONE初始化时,会创建EventQueueHandler的一个实例,用于管理The ONE所有事件,MessageEventGenerator事件就是在EventQueueHandler构造函数中被加入到事件队列的。相关源代码如下:

//EventQueueHandler.java
public EventQueueHandler() {
    ...
    //消息产生器事件
    
    else if (s.contains(CLASS_SETTING)) {
    
        String className = CLASS_PACKAGE + "." + s.getSetting(CLASS_SETTING); 
        //即input.MessageEventGenerator
        
        EventQueue eq = (EventQueue)s.createIntializedObject(className);
        
        queues.add(eq);  //加入到事件队列
        
    }
    
    ...
    
}

1.3配置文件

创建完实例后,开始创建消息,其中我们在default_settings.txt这一配置文件中配置消息产生的基本信息格式如下:

# 消息事件产生器类型
Events1.class = MessageEventGenerator
# 消息创建间隔,每隔(25,35)秒产生一个消息,间隔随机从(25,35)产生
Events1.interval = 25,35
# 消息大小,产生消息的大小随机从(min, max)取得,单位是字节
Events1.size = 500k,1M
# Sender/receiver address range, 值得注意的是,包含下限但不包含上限,即[0, 126)
Events1.hosts = 0,126
# receiver address range,是hosts的一个子集。同样,包含下限但不包含上限。若没有设置,被视为与hosts同
Events1.tohosts = 0, 126
# 消息名称的前缀(Message ID prefix),用于标识不同的generator产生的消息
Events1.prefix = M
# 创建消息的时间范围[min, max],默认情况是[0, Scenario.endTime],即整个仿真期间都可以创建消息
Events1.time = 500, 1000

1.4 消息Message的基本属性

描述一个消息Message的属性有:id,从哪里来到哪里去,创建和接收时间,TTL,大小等。Message的主要成员变量如下:

//Message.java
//identify 
private String id;
private int uniqueId;  //Unique ID of this message
private String    appID;  //Application ID of the application that created the message
//about DTNHost
private DTNHost from;
private DTNHost to;
private List path;  //消息经过的路径
private int size;  //bytes
private int initTtl;
private double timeReceived;
private double timeCreated;
private int responseSize;
private Message requestMsg;

2.消息创建

消息创建分两步:首先,由MessageEventGenerator.nextEvent()产生一个消息创建事件MessageCreateEvent;而后,当轮到处理MessageCreateEvent时,才真正创建一个消息。

2.1 消息创建事件

 处理MessageEventGenerator事件时,调用其nextEvent创建一个消息产生事件(只是一个事件,还不是消息)。更确切的说,World.update的this.nextEventQueue.nextEvent得到一个消息创建的外部事件。

相关源代码如下:

//MessageEventGenerator.java
public ExternalEvent nextEvent() 
{       
    from = drawHostAddress(this.hostRange);    
    to = drawToAddress(hostRange, from);    
    msgSize = drawMessageSize();    
    interval = drawNextEventTimeDiff(); //再过interval,再产生一个新的消息       
    MessageCreateEvent mce = new MessageCreateEvent(from, to, this.getID(), msgSize, responseSize, this.nextEventsTime);    
    return mce;
}

//MessageCreateEvent.java
public MessageCreateEvent(int from, int to, String id, int size, int responseSize, double time) 
{    
    super(from,to, id, time);    
    this.size = size;    
    this.responseSize = responseSize;
}

由此可见,MessageEventGenerator实际上是产生一系列消息创建事件,正如其名。  

2.2 创建消息

首先,需要获取消息创建事件,每隔updateInterval,World.java中的update()会逐一处理事件。相关源代码如下:

//World.java中的update()public void update () 
{
    ......    
    setNextEventQueue();  
    //找到一个事件队列,该事件队列含有本updateInterval可以处理的事件
    while (this.nextQueueEventTime <= runUntil) 
    {        
        simClock.setTime(this.nextQueueEventTime);
        ExternalEvent ee = this.nextEventQueue.nextEvent();  //取得事件
        ee.processEvent(this);  //处理事件
        updateHosts();  //update all hosts after every event
        setNextEventQueue();
    }
    
    ......
    
}

从上述代码可见,取得一个事件队列(setNextEventQueue,可能是EventQueue类型的MessageEventGenerator),紧接着处理之processEvent。processEvent()在这里对应于MessageCreateEvent的processEvent函数,旨在创建消息。相关源代码如下:

//MessageCreateEvent.javapublic void processEvent(World world)
{
    DTNHost to = world.getNodeByAddress(this.toAddr);
    DTNHost from = world.getNodeByAddress(this.fromAddr);
    Message m = new Message(from, to, this.id, this.size);
    m.setResponseSize(this.responseSize);    
    from.createNewMessage(m);   //创建消息
}

//DTNHost.java

DTNHost.createNewMessage --> MessageRouter.createNewMessage

//MessageRouter.java

public boolean createNewMessage(Message m) 
{
    m.setTtl(this.msgTtl);    
    m.addToMessages( true);     //将消息加入到HashMap<String, Message> messages
    return true;
}

至此,一个消息创建完毕。值得注意的是,当一个新消息被创建时,会触发消息监听器MessageListener,MessageListener是一个接口,实现该接口主要是一些reports。通俗理解就是消息被创建后,通知相关reports更新统计信息(如CreatedMessagesReport, MessageStatsReport)。相关源代码如下:

//MessageRouter.java
protected void addToMessages(Message m, boolean newMessage) 
{    
    this.messages.put(m.getId(), m);    
    if (newMessage) 
        {        
            for (MessageListener ml : this.mListeners) 
            {   //触发消息监听器
                ml.newMessage(m);
            }
        }
}

你可能感兴趣的:(one,the)