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

简介:
      这个系列的前两篇文章主要是根据自己的需求,对Thunderbird的源代码进行修改,改进了Thunderbird的现有功能,关注点都在Thunderbird的老本行---邮件客户端的实现上,那是否Thunderbird就仅仅是一个邮件客户端呢?在我看来,并非如此,它源自Mozilla内核,就继承了Mozilla平台的光荣传统,应该视为一个优秀的可扩展的开发平台,更进一步来看,Mozilla的文化深入其骨髓,可以看到后来Adobe的Flex,MicroSoft的WPF都吸收了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, 0, 0);//打开输出流,类型为阻塞型,无缓冲区
    }
    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, 1000, this.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



本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/05/19/1202823.html,如需转载请自行联系原作者
目录
相关文章
|
5月前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
3月前
|
Java 运维
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
52 2
|
3月前
|
JavaScript 前端开发 API
Chrome插件实现问题之 content_script.js能做什么
Chrome插件实现问题之 content_script.js能做什么
|
2月前
|
JavaScript 开发工具
Electron 开发过程中主进程的无法看到 console.log 输出怎么办
Electron 开发过程中主进程的无法看到 console.log 输出怎么办
|
2月前
|
机器学习/深度学习 数据可视化 搜索推荐
低代码开发是一种能够加速软件研发进程的高效开发方法
【8月更文挑战第4天】低代码开发是一种能够加速软件研发进程的高效开发方法
46 0
|
3月前
|
SQL 自然语言处理 网络协议
【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)
TCP(Transmission Control Protocol)连接是互联网上最常用的一种面向连接、可靠的、基于字节流的传输层通信协议。建立TCP连接需要经过著名的“三次握手”过程: 1. SYN(同步序列编号):客户端发送一个SYN包给服务器,并进入SYN_SEND状态,等待服务器确认。 2. SYN-ACK:服务器收到SYN包后,回应一个SYN-ACK(SYN+ACKnowledgment)包,告诉客户端其接收到了请求,并同意建立连接,此时服务器进入SYN_RECV状态。 3. ACK(确认字符):客户端收到服务器的SYN-ACK包后,发送一个ACK包给服务器,确认收到了服务器的确
179 1
|
3月前
|
NoSQL Linux Redis
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
|
5月前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
400 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
|
5月前
|
Java 调度 开发者
构建高效微服务架构:后端开发的新趋势深入理解操作系统之进程调度策略
【4月更文挑战第30天】 随着企业数字化转型的不断深入,传统的单体应用逐渐不能满足快速迭代和灵活部署的需求。微服务架构以其高度模块化、独立部署和易于扩展的特性,成为现代后端开发的重要趋势。本文将探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术选型以及可能面临的挑战。
|
5月前
|
监控 C++
C++ Qt开发:QProcess进程管理模块
Qt是一个跨平台的C++图形库,简化了窗体应用开发,支持通过拖放组件提升效率。本章节关注`QProcess`组件,它用于控制和管理进程,例如执行命令、运行可执行文件及与外部进程通信。`QProcess`提供多种方法如`start`、`waitForStarted`和`waitForFinished`等,实现启动、监控和交互。示例展示了如何使用`QProcess`获取系统进程和信息,通过`tasklist`和`systeminfo`命令,并将结果展示在`QTreeWidget`中。
C++ Qt开发:QProcess进程管理模块

相关实验场景

更多