专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » thunderbird:基于Mozilla Thunderbird的扩展开发( 5)---进程间通信的Socket篇(上) »正文

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

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

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

  本文就是开发个扩展展示TCP/IP 技术在Mozilla扩展开发中应用

  服务器端主代码:

 const tBirdBfServerUi =
 {
  tBirdBfServerOnLoad: function
  {//启动服务器
   // remove to avoid duplicate initialization
   removeEventListener("load", tBirdBfServerUi.tBirdBfServerOnLoad, true);
   tBirdBfCommon.IconPosition;//设置图标位置
  //创建服务器对象并
   var server = Components.es["@phinecos.cnblogs.com/TBbf/server;1"].getService(Components.erfaces.nsISupports).wrappedJSObject;
   server.initialize;
   server.addWindow(window);//保存当前窗口
   server = null;
  },
  tBirdBfServerOnClose: function
  {//关闭服务器
   // remove to avoid duplicate initialization
   removeEventListener("close", tBirdBfServerUi.tBirdBfServerOnClose, true);
  
  //移除当前窗口
   var server = Components.es["@dpwhite.com/thunderbirdbf/server;1"].getService(Components.erfaces.nsISupports).wrappedJSObject;
   server.removeWindow(window);
   server = null;
  }
 }
  
 addEventListener("load", tBirdBfServerUi.tBirdBfServerOnLoad, true);
 addEventListener("close", tBirdBfServerUi.tBirdBfServerOnClose, true);


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

  服务器类

const CI = Components.erfaces, CC = Components.es, CR = Components.results;
const Mail= "1";
const noMail = "0";
const serverError = "9";
  
tBirdBfServer.ID = Components.ID("{d2c9b4c6-2851-4d25-8cb6-3d3b037f8e1e}");//组件ID
tBirdBfServer.contractID = "@phinecos.cnblogs.com/TBbf/server;1";
tBirdBfServer.Description = "TBbf Server Service";
  
function tBirdBfServer
{
 this.utility = CC[utilityContractID].getService(CI.nsISupports).wrappedJSObject;//工具类对象
 this.prefs = CC["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefBranch);
 this.connections = CC["@mozilla.org/supports-.gif' />;1"].createInstance(CI.nsICollection);//客户端连接集合
 this.useAnimation = null;//是否使用动画效果
 this.mailStatus = noMail;//邮箱状态
 this.serverSocket = null;//服务器端
 this.port = null;//服务器端口
 this.windowCollection = CC["@mozilla.org/supports-.gif' />;1"].createInstance(CI.nsICollection);//保存窗口集合
 this.initialized = false;//是否已经
}
  
 broadcast: function
 {//向客户端发送数据
  var deadConnections = Array;//已断开连接
  var status = this.mailStatus;//获取当前邮箱状态
  var count = this.connections.Count;//来自客户端连接数目
  
  //依次向各个客户端发送服务器邮箱状态
  for(var i = 0; i < count; i)
  {
   var connection = this.connections.GetElementAt(i);//来自客户端连接
   connection = connection.wrappedJSObject;
  
   //发送数据给客户端
   (!connection.broadcast(status))
   {
    connection.closeSocket;//关闭此断开连接
    deadConnections[i] = connection;
   }
   
   {
    deadConnections[i] = null;
   }
  
   connection = null;
  }
  
  for(var i = 0; i < deadConnections.length; i)
  {//移除已经断开连接
   (deadConnections[i] != null)
   {
    this.removeConnection(deadConnections[i]);
   }
  }
  
  deadConnections = null;
  count = null;
 },
  
 addConnection: function(value)
 {//加入新来自客户端连接
  this.connections.AppendElement(value);
  },
  
 removeConnection: function(value)
 {//移除连接
  this.connections.RemoveElement(value);
 },
 getServerSocket: function
 {//创建服务器端并开始异步监听来自客户端request
  this.serverSocket = CC["@mozilla.org/network/server-;1"].createInstance(CI.nsIServerSocket);
  (!this.serverSocket)
  {
   alert("Unable to get a server ");
  }
  
  {
   try
   {
    this.serverSocket.init(this.port, false, -1);//化服务器端,绑定到端口号port
    this.serverSocket.asyncListen(tBirdBfServerSocketListener);//开始异步监听来自客户端请求
   }
   catch(e)
   {
     this.serverSocket = null;
   }
  }
 },
 closeServerSocket: function
 {//关闭服务器端
  (!this.serverSocket)
  {
   this.serverSocket.close(null);
   this.serverSocket = null;
  }
 },
 initialize: function
 {//化服务器
  (this.initialized)
  {//已经化过了
   ;
  }
  this.port = 25501;//设置服务器监听端口
  this.useAnimation = true;
  this.getServerSocket;//创建服务器端并开始监听
  this.monitorBf(true);//监控状态变化
  this.initialized = true;
  },
 monitorBf: function(isStarting)
 {//监控邮箱状态变化
  var sessionService = CC["@mozilla.org/messenger/services/session;1"].getService(CI.nsIMsgMailSession);
  (isStarting)
  {
   sessionService.AddFolderListener(tBirdBfServerBfStateListener, CI.nsIFolderListener.PropertyChanged);//增加监听者
  }
  
  {
   sessionService.RemoveFolderListener(tBirdBfServerBfStateListener, CI.nsIFolderListener.PropertyChanged);//移除监听者
  }
  
  sessionService = null;
 },
  
 closeAllConnections: function
 {//关闭所有来自客户端连接
  var count = this.connections.Count;
  for(var i = 0; i < count; i)
  {
   var connection = this.connections.GetElementAt(i);
   connection = connection.wrappedJSObject;
   connection.closeSocket;
   connection = null;
  }
  
  count = null;
  this.connections.Clear;
 },
  finalize: function
 {//析构
  (!this.initialized)
  {
   ;
  }
  
  this.closeServerSocket;//关闭服务器端
  this.monitorBf(false);//移除监听邮箱状态监听者
  this.closeAllConnections;//关闭所有来自客户端连接
 },
  
   updateUi: function(window)
 {//刷新界面状态
  var state;
  var tip = "T-Bird Bf: ";
  var status = window.document.getElementById("thunderbird-bf");
  
  switch(this.mailStatus)
  {
    noMail:
   {//没有新邮件
    tip this.getLocalizedString("noNewMail");
    state = "noMail";
    ;
   }
  
    Mail:
   {//有新邮件
    tip this.getLocalizedString("Mail");
    (this.useAnimation)
    {
     state = "MailAni"; // using g here due to animation
    }
    
    {
     state = "Mail";
    }
  
    ;
   }
  
   default:
   {//error
    this.utility.logError("Unexpected result: " + this.mailStatus);
    tip = this.getLocalizedString("weirdness");
    state = "weirdness";
    ;
   }
  }
  
  status.Attribute("tooltiptext", tip);
  status.Attribute("bfState", state);
  tip = null;
  state = null;
  status = null;
 },
  
 MailStatus: function(value)
 {//设置邮箱状态
  (this.MailStatus value)
  {//没有变化
   ;
  }
  this.mailStatus = value;
  //邮箱状态发生改变逐个窗口通知其更新状态,这些窗口都是服务器端Observer
  var server = CC[tBirdBfServer.contractID].getService(CI.nsISupports).wrappedJSObject;
  var windowCollection = server.getWindowCollection;
  var count = windowCollection.Count;
  for(var i = 0; i < count; i)
  {
   var window = windowCollection.GetElementAt(i);
   this.updateUi(window);//更新此窗口状态
   window = null;
  }
  
  this.broadcast;//将服务器邮箱状态通知给各个客户端
  
  windowCollection = null;
  count = null;
  server = null;
 },
  
check: function
 {//检查服务器邮箱状态
  tBirdBfServerBfStateListener.clearIntervalTimeout;//清除此前定时器
  this.MailStatus(this.checkServers);//实际检查动作
 },
  
 checkServers: function
 {
  try
  {
   const bfShowsMailReady = 0;
   //帐户管理器
   var accountManager = CC["@mozilla.org/messenger/account-manager;1"].getService(CI.nsIMsgAccountManager);
   (accountManager)
   {
     //获取此用户所有服务器
    var servers = accountManager.allServers;
    var numServers = servers.Count;
  
    for(var i = 0; i < numServers; i)
    {
     var server = servers.GetElementAt(i).QueryInterface(CI.nsIMsgIncomingServer);
  
     (server.rootFolder != server.rootMsgFolder)
     {
      continue;
     }
  
     (server.type != "pop3" && server.type != "imap")
     {
      (server accountManager.localFoldersServer)
      {
       alert("tBirdBfServer.checkServers"+server.prettyName + " appears to be Local Folders");
      }
      
      {
       alert("Non-pop3, IMAP, or Local Folders server found. Type is " + server.type + ", name is " + server.prettyName);
       continue;
      }
     }
     (server.bfState bfShowsMailReady)
     {//有新邮件到来
      server = null;
      servers = null;
      numServers = null;
      accountManager = null;
       Mail;
     }
    }
    //没有新邮件
    servers = null;
    numServers = null;
    accountManager = null;
     noMail;
   }
   
   {
    accountManager = null;
    this.utility.logError("Unable to get account manager");
     serverError;
   }
  }
  catch (e)
  {
   accountManager = null;
    serverError;
  }
 },


  来自客户端连接对象类:

function tBirdBfServerConnection
{
 this.wrappedJSObject = this;
}
  
tBirdBfServerConnection.prototype =
{
 : null,//客户端对应
 outputStream: null,//输出流
  
 Socket: function(value)
 {//保存来自客户端连接
  try
  {
   this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流类型为阻塞型无缓冲区
  }
  catch(e)
  {
    false;
  }
  (!this.outputStream)
  {
    false;
  }
  this. = value;
   true;
 },
  
 closeSocket: function
 {//关闭来自客户端
  (this.outputStream)
  {//关闭输出流
   this.outputStream.close(null);
   this.outputStream = null;
  }
  (this.)
  {//关闭对应
   this..close(null);
   this. = null;
  }
 },
  
 broadcast: function(value)
 {//向客户端发送数据
  (!this.outputStream)
  {
   this.closeSocket;
    false;
  }
  try
  {
   this.outputStream.write(value, value.length);//发送数据
  }
  catch (e)
  {
   this.closeSocket;
    false;
  }
   true;
 }
}


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

function tBirdBfServerConnection
{
 this.wrappedJSObject = this;
}
  
tBirdBfServerConnection.prototype =
{
 : null,//客户端对应
 outputStream: null,//输出流
  
 Socket: function(value)
 {//保存来自客户端连接
  try
  {
   this.outputStream = value.openOutputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输出流类型为阻塞型无缓冲区
  }
  catch(e)
  {
    false;
  }
  (!this.outputStream)
  {
    false;
  }
  this. = value;
   true;
 },
  
 closeSocket: function
 {//关闭来自客户端
  (this.outputStream)
  {//关闭输出流
   this.outputStream.close(null);
   this.outputStream = null;
  }
  (this.)
  {//关闭对应
   this..close(null);
   this. = null;
  }
 },
  
 broadcast: function(value)
 {//向客户端发送数据
  (!this.outputStream)
  {
   this.closeSocket;
    false;
  }
  try
  {
   this.outputStream.write(value, value.length);//发送数据
  }
  catch (e)
  {
   this.closeSocket;
    false;
  }
   true;
 }
}
  
const tBirdBfServerSocketListener =
{
 onSocketAccepted: function(serverSocket, clientSocket)
 {//接受来自客户端请求
  var connection = tBirdBfServerConnection;//新建个连接对象
  //保存当前接收连接
  (connection.Socket(clientSocket))
  {
   var server = CC[tBirdBfServer.contractID].getService(CI.nsISupports).wrappedJSObject;
   //向客户端发送数据
   (connection.broadcast(server.getMailStatus))
   {
    server.addConnection(connection);//保存连接对象到在线连接集合中
   }
   
   {
    alert("connection NOT added");
   }
   server = null;
  }
  
  {
   alert("Creating connection failed");
  }
  connection = null;
 },
  
 onStopListening: function(serverSocket, status)
 {//服务器停止监听
   alert("Server has stopped listening");
 }
}


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

const tBirdBfServerBfStateListener =
{
 timer: null,//定时器负责定时检查邮箱状态
 clearIntervalTimeout: function
 {//清除定时器
  (this.timer)
  {
   this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
   this.timer.cancel;
   this.timer = null;
  }
  
  {
   alert("Timer is null");
  }
 },
  
 OnItemIntPropertyChanged: function(item, property, oldValue, Value)
 {//参见Thunderbird源代码负责监视各个文件夹属性变化,当有新邮件到来时property值为“BfState”
  (property.toString != "BfState")
  {
   ;
  }
  this.clearIntervalTimeout;
  //启动个定时器
  this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
  this.timer.initWithCallback(tBirdBfServerCheckCallback, 1000, this.timer.TYPE_ONE_SHOT);
 }
}


  实际检查邮箱状态处理过程放在tBirdBfServerCheckCallback

const tBirdBfServerCheckCallback =
{//定时检查邮箱状态处理
 noty: function(timer)
 {
  var server = CC[tBirdBfServer.contractID].getService(CI.nsISupports).wrappedJSObject;
  server.check;//检查邮箱状态
  server = null;
 }
}




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



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: