基于Mozilla Thunderbird的扩展开发(五)---进程间通信之Socket篇(上)

     

20080506.bmp

Mozilla扩展系列链接:

1浅谈基于Mozilla Thunderbird的扩展开发

2基于Mozilla平台的扩展开发(续)----XPCOM组件篇

3基于Mozilla Thunderbird的扩展开发(三)---如何获取邮件的完整信息

4基于Mozilla Thunderbird的扩展开发(四)---修改源代码实现自动保存附件

5基于Mozilla Thunderbird的扩展开发(五)---进程间通信之Socket篇(上)

      这个系列的前两篇文章主要是根据自己的需求,对Thunderbird的源代码进行修改,改进了Thunderbird的现有功能,关注点都在Thunderbird的老本行---邮件客户端的实现上,那是否Thunderbird就仅仅是一个邮件客户端呢?在我看来,并非如此,它源自Mozilla内核,就继承了Mozilla平台的光荣传统,应该视为一个优秀的可扩展的开发平台,更进一步来看,Mozilla的文化深入其骨髓,可以看到后来AdobeFlex,MicroSoftWPF都吸收了Mozilla平台界面与逻辑相分离的思想,所以接下来几篇文章我想写一个比较有意思的方面----进程间通信。

      进程间通信的概念在操作系统中有过详细的介绍,方法很多,我主要关注其中两种:socket通信,Pipe(管道)通信。

      本文的目的就是开发一个扩展,展示TCP/IP socket技术在Mozilla扩展开发中的应用。

服务器端主代码:

  const tBirdBiffServerUi  =
  
{
    tBirdBiffServerOnLoad: 
function()
    
{//启动服务器
      // remove to avoid duplicate initialization
      removeEventListener("load", tBirdBiffServerUi.tBirdBiffServerOnLoad, true);
      tBirdBiffCommon.setIconPosition();
//设置图标位置
    //创建服务器对象并初始化
      var server = Components.classes["@phinecos.cnblogs.com/TBbiff/server;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
      server.initialize();
      server.addWindow(window);
//保存当前窗口
      server = null;
    }
,
    tBirdBiffServerOnClose: 
function()
    
{//关闭服务器
      // remove to avoid duplicate initialization
      removeEventListener("close", tBirdBiffServerUi.tBirdBiffServerOnClose, true);

    
//移除当前窗口
      var server = Components.classes["@dpwhite.com/thunderbirdbiff/server;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
      server.removeWindow(window);
      server 
= null;
    }

  }


  addEventListener(
" load " , tBirdBiffServerUi.tBirdBiffServerOnLoad,  true );
  addEventListener(
" close " , tBirdBiffServerUi.tBirdBiffServerOnClose,  true );


服务器类,负责创建服务器端socket,并异步监听来自客户端的请求,管理邮箱状态的变化和来自客户端的连接。

服务器类


服务器监听类,负责监听来自客户端的各个请求:

function  tBirdBiffServerConnection()
{
  
this.wrappedJSObject = this;
}


tBirdBiffServerConnection.prototype 
=
{
  socket: 
null,//客户端对应的socket
  outputStream: null,//输出流

  setSocket: 
function(value)
  
{//保存来自客户端的socket连接
    try
    
{
      
this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 00);//打开输出流,类型为阻塞型,无缓冲区
    }

    
catch(e)
    
{
       
return false;
    }

    
if(!this.outputStream)
    
{
      
return false;
    }

    
this.socket = value;
    
return true;
  }
,

  closeSocket: 
function()
  
{//关闭来自客户端的socket
    if(this.outputStream)
    
{//关闭输出流
      this.outputStream.close(null);
      
this.outputStream = null;
    }

    
if(this.socket)
    
{//关闭对应的socket
      this.socket.close(null);
      
this.socket = null;
    }

  }
,

  broadcast: 
function(value)
  
{//向客户端发送数据
    if(!this.outputStream)
    
{
      
this.closeSocket();
      
return false;
    }

    
try
    
{
      
this.outputStream.write(value, value.length);//发送数据
    }

    
catch (e)
    
{
      
this.closeSocket();
      
return false;
    }

    
return true;
  }

}


const tBirdBiffServerSocketListener 
=
{
  onSocketAccepted: 
function(serverSocket, clientSocket)
  
{//接受来自客户端的请求
    var connection = new tBirdBiffServerConnection();//新建一个连接对象
    //保存当前接收的连接
    if(connection.setSocket(clientSocket))
    
{
      
var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
      
//向客户端发送数据
      if(connection.broadcast(server.getMailStatus()))
      
{
        server.addConnection(connection);
//保存连接对象到在线连接集合中
      }

      
else
      
{
        alert(
"connection NOT added");
      }

      server 
= null;
    }

    
else
    
{
      alert(
"Creating connection failed");
    }

    connection 
= null;
  }
,

  onStopListening: 
function(serverSocket, status)
  
{//服务器停止监听
     alert("Server socket has stopped listening");
  }

}


服务器邮箱状态监听者,负责监视邮箱的状态变化:

const tBirdBiffServerBiffStateListener  =
{
  timer: 
null,//定时器,负责定时检查邮箱状态
  clearIntervalTimeout: function()
  
{//清除定时器
    if(this.timer)
    
{
      
this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
      
this.timer.cancel();
      
this.timer = null;
    }

    
else
    
{
      alert(
"Timer is null");
    }

  }
,

  OnItemIntPropertyChanged: 
function(item, property, oldValue, newValue)
  
{//参见Thunderbird源代码,此函数负责监视各个文件夹的属性变化,当有新邮件到来时,property的值为“BiffState”
    if(property.toString() != "BiffState")
    
{
      
return;
    }

    
this.clearIntervalTimeout();
    
//启动一个定时器
    this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
    
this.timer.initWithCallback(tBirdBiffServerCheckCallback, 1000this.timer.TYPE_ONE_SHOT);
  }

}

实际的检查邮箱状态的处理过程放在tBirdBiffServerCheckCallback函数中。

const tBirdBiffServerCheckCallback  =
{//定时检查邮箱状态的处理函数
  notify: function(timer)
  
{
    
var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
    server.check();
//检查邮箱状态
    server = null;
  }

}


   Ok,本文用
javascript,遵循XPCOM规范实现了一个简单的TCP服务器,服务器类型为阻塞式I/O,客户端代码将在下一篇文章中介绍。

 Reference:

1 https://addons.mozilla.org/en-US/thunderbird/addon/3788

你可能感兴趣的:(socket)