这个系列的前两篇文章主要是根据自己的需求,对Thunderbird的源代码进行修改,改进了Thunderbird的现有功能,关注点都在Thunderbird的老本行---邮件客户端的实现上,那是否Thunderbird就仅仅是一个邮件客户端呢?在我看来,并非如此,它源自Mozilla内核,就继承了Mozilla平台的光荣传统,应该视为一个优秀的可扩展的开发平台,更进一步来看,Mozilla的文化深入其骨髓可以看到后来Adobe的Flex,MicroSoft的WPF都吸收了Mozilla平台界面与逻辑相分离的思想,所以接下来几篇文章我想写一个比较有意思的方面----进程间通信。
      进程间通信的概念在操作系统中有过详细的介绍,方法很多,我主要关注两种:socket通信,Pipe(管道)通信。
      本文的目的就是开发一个扩展,展示TCP/IP socket技术在Mozilla扩展开发中的应用。
    
      
      这个系列的前两篇文章主要是根据自己的需求,对Thunderbird的源代码进行修改,改进了Thunderbird的现有功能,关注点都在Thunderbird的老本行---邮件客户端的实现上,那是否Thunderbird就仅仅是一个邮件客户端呢?在我看来,并非如此,它源自Mozilla内核,就继承了Mozilla平台的光荣传统,应该视为一个优秀的可扩展的开发平台,更进一步来看,Mozilla的文化深入其骨髓,可以看到后来Adobe的Flex,MicroSoft的WPF都吸收了Mozilla平台界面与逻辑相分离的思想,所以接下来几篇文章我想写一个比较有意思的方面----进程间通信。
      进程间通信的概念在操作系统中有过详细的介绍,方法很多,我主要关注其中两种:socket通信,Pipe(管道)通信。
      本文的目的就是开发一个扩展,展示TCP/IP socket技术在Mozilla扩展开发中的应用。
服务器端主代码:
 const tBirdBiffServerUi =
  const tBirdBiffServerUi =

 
   {
{
 tBirdBiffServerOnLoad: function()
    tBirdBiffServerOnLoad: function()

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

 
     {//关闭服务器
{//关闭服务器
 // remove to avoid duplicate initialization
      // remove to avoid duplicate initialization
 removeEventListener("close", tBirdBiffServerUi.tBirdBiffServerOnClose, true);
      removeEventListener("close", tBirdBiffServerUi.tBirdBiffServerOnClose, true);

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

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

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

 服务器类
服务器类
 const CI = Components.interfaces, CC = Components.classes, CR = Components.results;
const CI = Components.interfaces, CC = Components.classes, CR = Components.results;
 const newMail= "1";
const newMail= "1";
 const noMail = "0";
const noMail = "0";
 const serverError = "9";
const serverError = "9";

 tBirdBiffServer.classID = Components.ID("{d2c9b4c6-2851-4d25-8cb6-3d3b037f8e1e}");//组件ID
tBirdBiffServer.classID = Components.ID("{d2c9b4c6-2851-4d25-8cb6-3d3b037f8e1e}");//组件ID
 tBirdBiffServer.contractID = "@phinecos.cnblogs.com/TBbiff/server;1";
tBirdBiffServer.contractID = "@phinecos.cnblogs.com/TBbiff/server;1";
 tBirdBiffServer.classDescription = "TBbiff Server Service";
tBirdBiffServer.classDescription = "TBbiff Server Service";

 function tBirdBiffServer()
function tBirdBiffServer()


 {
{
 this.utility = CC[utilityContractID].getService(CI.nsISupports).wrappedJSObject;//工具类对象
  this.utility = CC[utilityContractID].getService(CI.nsISupports).wrappedJSObject;//工具类对象
 this.prefs = CC["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefBranch);
  this.prefs = CC["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefBranch);
 this.connections = CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//客户端连接集合
  this.connections = CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//客户端连接集合
 this.useAnimation = null;//是否使用动画效果
  this.useAnimation = null;//是否使用动画效果
 this.mailStatus = noMail;//邮箱状态
  this.mailStatus = noMail;//邮箱状态
 this.serverSocket = null;//服务器端socket
  this.serverSocket = null;//服务器端socket
 this.port = null;//服务器端口
  this.port = null;//服务器端口
 this.windowCollection = CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//保存的窗口集合
  this.windowCollection = CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//保存的窗口集合
 this.initialized = false;//是否已经初始化
  this.initialized = false;//是否已经初始化
 }
}

 broadcast: function()
  broadcast: function()

 
   {//向客户端发送数据
{//向客户端发送数据
 var deadConnections = new Array();//已断开的连接
    var deadConnections = new Array();//已断开的连接
 var status = this.mailStatus;//获取当前邮箱状态
    var status = this.mailStatus;//获取当前邮箱状态
 var count = this.connections.Count();//来自客户端的连接数目
    var count = this.connections.Count();//来自客户端的连接数目

 //依次向各个客户端发送服务器的邮箱状态
    //依次向各个客户端发送服务器的邮箱状态
 for(var i = 0; i < count; i++)
    for(var i = 0; i < count; i++)

 
     {
{
 var connection = this.connections.GetElementAt(i);//来自客户端的连接
      var connection = this.connections.GetElementAt(i);//来自客户端的连接
 connection = connection.wrappedJSObject;
      connection = connection.wrappedJSObject;
 
    
 //发送数据给客户端
      //发送数据给客户端
 if(!connection.broadcast(status))
      if(!connection.broadcast(status))

 
       {
{
 connection.closeSocket();//关闭此断开的连接
        connection.closeSocket();//关闭此断开的连接
 deadConnections[i] = connection;
        deadConnections[i] = connection;
 }
      }
 else
      else

 
       {
{
 deadConnections[i] = null;
        deadConnections[i] = null;
 }
      }

 connection = null;
      connection = null;
 }
    }

 for(var i = 0; i < deadConnections.length; i++)
    for(var i = 0; i < deadConnections.length; i++)

 
     {//移除已经断开的连接
{//移除已经断开的连接
 if(deadConnections[i] != null)
      if(deadConnections[i] != null)

 
       {
{
 this.removeConnection(deadConnections[i]);
        this.removeConnection(deadConnections[i]);
 }
      }
 }
    }

 deadConnections = null;
    deadConnections = null;
 count = null;
    count = null;
 },
  },

 addConnection: function(value)
  addConnection: function(value)

 
   {//加入新的来自客户端的连接
{//加入新的来自客户端的连接
 this.connections.AppendElement(value);
    this.connections.AppendElement(value);
 },
   },

 removeConnection: function(value)
  removeConnection: function(value)

 
   {//移除连接
{//移除连接
 this.connections.RemoveElement(value);
    this.connections.RemoveElement(value);
 },
  },
 getServerSocket: function()
  getServerSocket: function()

 
   {//创建服务器端socket,并开始异步监听来自客户端的request
{//创建服务器端socket,并开始异步监听来自客户端的request
 this.serverSocket = CC["@mozilla.org/network/server-socket;1"].createInstance(CI.nsIServerSocket);
    this.serverSocket = CC["@mozilla.org/network/server-socket;1"].createInstance(CI.nsIServerSocket);
 if(!this.serverSocket)
    if(!this.serverSocket)

 
     {
{
 alert("Unable to get a server socket");
      alert("Unable to get a server socket");
 }
    }
 else
    else

 
     {
{
 try
      try

 
       {
{
 this.serverSocket.init(this.port, false, -1);//初始化服务器端socket,绑定到端口号port
        this.serverSocket.init(this.port, false, -1);//初始化服务器端socket,绑定到端口号port
 this.serverSocket.asyncListen(tBirdBiffServerSocketListener);//开始异步监听来自客户端的请求
        this.serverSocket.asyncListen(tBirdBiffServerSocketListener);//开始异步监听来自客户端的请求
 }
      }
 catch(e)
      catch(e)

 
       {
{
 this.serverSocket = null;
         this.serverSocket = null;
 }
      }
 }
    }
 },
  },
 closeServerSocket: function()
  closeServerSocket: function()

 
   {//关闭服务器端socket
{//关闭服务器端socket
 if(!this.serverSocket)
    if(!this.serverSocket)

 
     {
{
 this.serverSocket.close(null);
      this.serverSocket.close(null);
 this.serverSocket = null;
      this.serverSocket = null;
 }
    }
 },
  },
 initialize: function()
  initialize: function()

 
   {//初始化服务器
{//初始化服务器
 if(this.initialized)
    if(this.initialized)

 
     {//已经初始化过了
{//已经初始化过了
 return;
      return;
 }
    }
 this.port = 25501;//设置服务器监听端口
    this.port = 25501;//设置服务器监听端口
 this.useAnimation = true;
    this.useAnimation = true;
 this.getServerSocket();//创建服务器端socket并开始监听
    this.getServerSocket();//创建服务器端socket并开始监听
 this.monitorBiff(true);//监控状态变化
    this.monitorBiff(true);//监控状态变化
 this.initialized = true;
    this.initialized = true;
 },
   },
 monitorBiff: function(isStarting)
  monitorBiff: function(isStarting)

 
   {//监控邮箱状态变化
{//监控邮箱状态变化
 var sessionService = CC["@mozilla.org/messenger/services/session;1"].getService(CI.nsIMsgMailSession);
    var sessionService = CC["@mozilla.org/messenger/services/session;1"].getService(CI.nsIMsgMailSession);
 if(isStarting)
    if(isStarting)

 
     {
{
 sessionService.AddFolderListener(tBirdBiffServerBiffStateListener, CI.nsIFolderListener.intPropertyChanged);//增加监听者
      sessionService.AddFolderListener(tBirdBiffServerBiffStateListener, CI.nsIFolderListener.intPropertyChanged);//增加监听者
 }
    }
 else
    else

 
     {
{
 sessionService.RemoveFolderListener(tBirdBiffServerBiffStateListener, CI.nsIFolderListener.intPropertyChanged);//移除监听者
      sessionService.RemoveFolderListener(tBirdBiffServerBiffStateListener, CI.nsIFolderListener.intPropertyChanged);//移除监听者
 }
    }

 sessionService = null;
    sessionService = null;
 },
  },

 closeAllConnections: function()
  closeAllConnections: function()

 
   {//关闭所有来自客户端的连接
{//关闭所有来自客户端的连接
 var count = this.connections.Count();
    var count = this.connections.Count();
 for(var i = 0; i < count; i++)
    for(var i = 0; i < count; i++)

 
     {
{
 var connection = this.connections.GetElementAt(i);
      var connection = this.connections.GetElementAt(i);
 connection = connection.wrappedJSObject;
      connection = connection.wrappedJSObject;
 connection.closeSocket();
      connection.closeSocket();
 connection = null;
      connection = null;
 }
    }

 count = null;
    count = null;
 this.connections.Clear();
    this.connections.Clear();
 },
  },
 finalize: function()
   finalize: function()

 
   {//析构函数
{//析构函数
 if(!this.initialized)
    if(!this.initialized)

 
     {
{
 return;
      return;
 }
    }

 this.closeServerSocket();//关闭服务器端socket
    this.closeServerSocket();//关闭服务器端socket
 this.monitorBiff(false);//移除监听邮箱状态的监听者
    this.monitorBiff(false);//移除监听邮箱状态的监听者
 this.closeAllConnections();//关闭所有来自客户端的连接
    this.closeAllConnections();//关闭所有来自客户端的连接
 },
  },

 updateUi: function(window)
      updateUi: function(window)

 
   {//刷新界面状态
{//刷新界面状态
 var state;
    var state;
 var tip = "T-Bird Biff: ";
    var tip = "T-Bird Biff: ";
 var status = window.document.getElementById("thunderbird-biff");
    var status = window.document.getElementById("thunderbird-biff");

 switch(this.mailStatus)
    switch(this.mailStatus)

 
     {
{
 case noMail:
      case noMail:

 
       {//没有新邮件
{//没有新邮件
 tip += this.getLocalizedString("noNewMail");
        tip += this.getLocalizedString("noNewMail");
 state = "noMail";
        state = "noMail";
 break;
        break;
 }
      }

 case newMail:
      case newMail:

 
       {//有新邮件
{//有新邮件
 tip += this.getLocalizedString("newMail");
        tip += this.getLocalizedString("newMail");
 if(this.useAnimation)
        if(this.useAnimation)

 
         {
{
 state = "newMailAni"; // using gif here due to animation
          state = "newMailAni"; // using gif here due to animation
 }
        }
 else
        else

 
         {
{
 state = "newMail";
          state = "newMail";
 }
        }

 break;
        break;
 }
      }

 default:
      default:

 
       {//error
{//error
 this.utility.logError("Unexpected result: " + this.mailStatus);
        this.utility.logError("Unexpected result: " + this.mailStatus);
 tip = this.getLocalizedString("weirdness");
        tip = this.getLocalizedString("weirdness");
 state = "weirdness";
        state = "weirdness";
 break;
        break;
 }
      }
 }
    }

 status.setAttribute("tooltiptext",  tip);
    status.setAttribute("tooltiptext",  tip);
 status.setAttribute("biffState",  state);
    status.setAttribute("biffState",  state);
 tip = null;
    tip = null;
 state = null;
    state = null;
 status = null;
    status = null;
 },
  },

 setMailStatus: function(value)
  setMailStatus: function(value)

 
   {//设置邮箱状态
{//设置邮箱状态
 if(this.MailStatus == value)
    if(this.MailStatus == value)

 
     {//没有变化
{//没有变化
 return;
      return;
 }
    }
 this.mailStatus = value;
    this.mailStatus = value;
 //邮箱状态发生改变,逐个窗口通知其更新状态,这些窗口都是服务器端的Observer
    //邮箱状态发生改变,逐个窗口通知其更新状态,这些窗口都是服务器端的Observer
 var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
    var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
 var windowCollection = server.getWindowCollection();
    var windowCollection = server.getWindowCollection();
 var count = windowCollection.Count();
    var count = windowCollection.Count();
 for(var i = 0; i < count; i++)
    for(var i = 0; i < count; i++)

 
     {
{
 var window = windowCollection.GetElementAt(i);
      var window = windowCollection.GetElementAt(i);
 this.updateUi(window);//更新此窗口状态
      this.updateUi(window);//更新此窗口状态
 window = null;
      window = null;
 }
    }

 this.broadcast();//将服务器的邮箱状态通知给各个客户端
    this.broadcast();//将服务器的邮箱状态通知给各个客户端

 windowCollection = null;
    windowCollection = null;
 count = null;
    count = null;
 server = null;
    server = null;
 },
  },

 check: function()
check: function()

 
   {//检查服务器邮箱状态
{//检查服务器邮箱状态
 tBirdBiffServerBiffStateListener.clearIntervalTimeout();//清除此前的定时器
    tBirdBiffServerBiffStateListener.clearIntervalTimeout();//清除此前的定时器
 this.setMailStatus(this.checkServers());//实际的检查动作
    this.setMailStatus(this.checkServers());//实际的检查动作
 },
  },

 checkServers: function()
  checkServers: function()

 
   {
{
 try
    try

 
     {
{
 const biffShowsMailReady = 0;
      const biffShowsMailReady = 0;
 //帐户管理器
      //帐户管理器
 var accountManager = CC["@mozilla.org/messenger/account-manager;1"].getService(CI.nsIMsgAccountManager);
      var accountManager = CC["@mozilla.org/messenger/account-manager;1"].getService(CI.nsIMsgAccountManager);
 if(accountManager)
      if(accountManager)

 
       {
{
 //获取此用户的所有服务器
          //获取此用户的所有服务器
 var servers = accountManager.allServers;
        var servers = accountManager.allServers;
 var numServers = servers.Count();
        var numServers = servers.Count();

 for(var i = 0; i < numServers; i++)
        for(var i = 0; i < numServers; i++)

 
         {
{
 var server = servers.GetElementAt(i).QueryInterface(CI.nsIMsgIncomingServer);
          var server = servers.GetElementAt(i).QueryInterface(CI.nsIMsgIncomingServer);
 
    
 if(server.rootFolder != server.rootMsgFolder)
          if(server.rootFolder != server.rootMsgFolder)

 
           {
{
 continue;
            continue;
 }
          }

 if(server.type != "pop3" && server.type != "imap")
          if(server.type != "pop3" && server.type != "imap")

 
           {
{
 if(server == accountManager.localFoldersServer)
            if(server == accountManager.localFoldersServer)

 
             {
{
 alert("tBirdBiffServer.checkServers"+server.prettyName + " appears to be Local Folders");
             alert("tBirdBiffServer.checkServers"+server.prettyName + " appears to be Local Folders");
 }
            }
 else
            else

 
             {
{
 alert("Non-pop3, IMAP, or Local Folders server found. Type is " + server.type + ", name is " + server.prettyName);
              alert("Non-pop3, IMAP, or Local Folders server found. Type is " + server.type + ", name is " + server.prettyName);
 continue;
              continue;
 }
            }
 }
          }
 if(server.biffState == biffShowsMailReady)
          if(server.biffState == biffShowsMailReady)

 
           {//有新邮件到来
{//有新邮件到来
 server = null;
            server = null;
 servers = null;
            servers = null;
 numServers = null;
            numServers = null;
 accountManager = null;
            accountManager = null;
 return newMail;
            return newMail;
 }
          }
 }
        }
 //没有新邮件
        //没有新邮件
 servers = null;
        servers = null;
 numServers = null;
        numServers = null;
 accountManager = null;
        accountManager = null;
 return noMail;
        return noMail;
 }
      }
 else
      else

 
       {
{
 accountManager = null;
        accountManager = null;
 this.utility.logError("Unable to get account manager");
        this.utility.logError("Unable to get account manager");
 return serverError;
        return serverError;
 }
      }
 }
    }
 catch (e)
    catch (e)

 
     {
{
 accountManager = null;
      accountManager = null;
 return serverError;
      return serverError;
 }
    }
 },
  },

 来自客户端的连接对象类:
来自客户端的连接对象类:
 function tBirdBiffServerConnection()
function tBirdBiffServerConnection()


 {
{
 this.wrappedJSObject = this;
  this.wrappedJSObject = this;
 }
}

 tBirdBiffServerConnection.prototype =
tBirdBiffServerConnection.prototype =


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

 setSocket: function(value)
  setSocket: function(value)

 
   {//保存来自客户端的socket连接
{//保存来自客户端的socket连接
 try
    try

 
     {
{
 this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流,类型为阻塞型,无缓冲区
      this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流,类型为阻塞型,无缓冲区
 }
    }
 catch(e)
    catch(e)

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

 
     {
{
 return false;
      return false;
 }
    }
 this.socket = value;
    this.socket = value;
 return true;
    return true;
 },
  },

 closeSocket: function()
  closeSocket: function()

 
   {//关闭来自客户端的socket
{//关闭来自客户端的socket
 if(this.outputStream)
    if(this.outputStream)

 
     {//关闭输出流
{//关闭输出流
 this.outputStream.close(null);
      this.outputStream.close(null);
 this.outputStream = null;
      this.outputStream = null;
 }
    }
 if(this.socket)
    if(this.socket)

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

 broadcast: function(value)
  broadcast: function(value)

 
   {//向客户端发送数据
{//向客户端发送数据
 if(!this.outputStream)
    if(!this.outputStream)

 
     {
{
 this.closeSocket();
      this.closeSocket();
 return false;
      return false;
 }
    }
 try
    try

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

 
     {
{
 this.closeSocket();
      this.closeSocket();
 return false;
      return false;
 }
    }
 return true;
    return true;
 }
  }
 }
}

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


 {
{
 this.wrappedJSObject = this;
  this.wrappedJSObject = this;
 }
}

 tBirdBiffServerConnection.prototype =
tBirdBiffServerConnection.prototype =


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

 setSocket: function(value)
  setSocket: function(value)

 
   {//保存来自客户端的socket连接
{//保存来自客户端的socket连接
 try
    try

 
     {
{
 this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流,类型为阻塞型,无缓冲区
      this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流,类型为阻塞型,无缓冲区
 }
    }
 catch(e)
    catch(e)

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

 
     {
{
 return false;
      return false;
 }
    }
 this.socket = value;
    this.socket = value;
 return true;
    return true;
 },
  },

 closeSocket: function()
  closeSocket: function()

 
   {//关闭来自客户端的socket
{//关闭来自客户端的socket
 if(this.outputStream)
    if(this.outputStream)

 
     {//关闭输出流
{//关闭输出流
 this.outputStream.close(null);
      this.outputStream.close(null);
 this.outputStream = null;
      this.outputStream = null;
 }
    }
 if(this.socket)
    if(this.socket)

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

 broadcast: function(value)
  broadcast: function(value)

 
   {//向客户端发送数据
{//向客户端发送数据
 if(!this.outputStream)
    if(!this.outputStream)

 
     {
{
 this.closeSocket();
      this.closeSocket();
 return false;
      return false;
 }
    }
 try
    try

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

 
     {
{
 this.closeSocket();
      this.closeSocket();
 return false;
      return false;
 }
    }
 return true;
    return true;
 }
  }
 }
}

 const tBirdBiffServerSocketListener =
const tBirdBiffServerSocketListener =


 {
{
 onSocketAccepted: function(serverSocket, clientSocket)
  onSocketAccepted: function(serverSocket, clientSocket)

 
   {//接受来自客户端的请求
{//接受来自客户端的请求
 var connection = new tBirdBiffServerConnection();//新建一个连接对象
    var connection = new tBirdBiffServerConnection();//新建一个连接对象
 //保存当前接收的连接
    //保存当前接收的连接
 if(connection.setSocket(clientSocket))
    if(connection.setSocket(clientSocket))

 
     {
{
 var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
      var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
 //向客户端发送数据
      //向客户端发送数据
 if(connection.broadcast(server.getMailStatus()))
      if(connection.broadcast(server.getMailStatus()))

 
       {
{
 server.addConnection(connection);//保存连接对象到在线连接集合中
        server.addConnection(connection);//保存连接对象到在线连接集合中
 }
      }
 else
      else

 
       {
{
 alert("connection NOT added");
        alert("connection NOT added");
 }
      }
 server = null;
      server = null;
 }
    }
 else
    else

 
     {
{
 alert("Creating connection failed");
      alert("Creating connection failed");
 }
    }
 connection = null;
    connection = null;
 },
  },

 onStopListening: function(serverSocket, status)
  onStopListening: function(serverSocket, status)

 
   {//服务器停止监听
{//服务器停止监听
 alert("Server socket has stopped listening");
     alert("Server socket has stopped listening");
 }
  }
 }
}

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


 {
{
 timer: null,//定时器,负责定时检查邮箱状态
  timer: null,//定时器,负责定时检查邮箱状态
 clearIntervalTimeout: function()
  clearIntervalTimeout: function()

 
   {//清除定时器
{//清除定时器
 if(this.timer)
    if(this.timer)

 
     {
{
 this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
      this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
 this.timer.cancel();
      this.timer.cancel();
 this.timer = null;
      this.timer = null;
 }
    }
 else
    else

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

 OnItemIntPropertyChanged: function(item, property, oldValue, newValue)
  OnItemIntPropertyChanged: function(item, property, oldValue, newValue)

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

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

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


 {//定时检查邮箱状态的处理函数
{//定时检查邮箱状态的处理函数
 notify: function(timer)
  notify: function(timer)

 
   {
{
 var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
    var server = CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
 server.check();//检查邮箱状态
    server.check();//检查邮箱状态
 server = null;
    server = null;
 }
  }
 }
}

   Ok,本文用javascript,遵循XPCOM规范实现了一个简单的TCP服务器,服务器类型为阻塞式I/O,客户端代码将在下一篇文章中介绍。
 Reference:
1, https://addons.mozilla.org/en-US/thunderbird/addon/3788