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

简介:
      在上一篇《基于Mozilla Thunderbird的扩展开发(五)---进程间通信之Socket篇(上)》中开发了一个简单的TCP服务器,本文将介绍其对应的客户端。
   客户端代码:
   
 const tBirdBiffClientUi =
  {
    tBirdBiffClientOnLoad: function()
    {
      // remove to avoid duplicate initialization
      removeEventListener("load", tBirdBiffClientUi.tBirdBiffClientOnLoad, true);
      //初始化客户端
      var client = Components.classes["@phinecos.cnblogs.com/TBbiff/client;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
      client.initialize();
      var windowCount = client.getWindowCollection().Count();
      client.addWindow(window);
      client = null;
      tBirdBiffClientObserver.updateUi();//更新UI
      // register for notifications
      var service = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
      service.addObserver(tBirdBiffClientObserver, "thunderbirdBiff.uiUpdate", false);//加入监控者 
      service = null;
    },

    tBirdBiffClientOnClose: function()
    {
      // remove to avoid duplicate initialization
      removeEventListener("close", tBirdBiffClientUi.tBirdBiffClientOnClose, true);
      var service = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
      service.removeObserver(tBirdBiffClientObserver, "thunderbirdBiff.uiUpdate");//移除监控者
      service = null;

      var client = Components.classes["@phinecos.cnblogs.com/TBbiff/client;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
      client.removeWindow(window);//移除窗口
      client = null;
    }
  }
  addEventListener("load", tBirdBiffClientUi.tBirdBiffClientOnLoad, true);
  addEventListener("close", tBirdBiffClientUi.tBirdBiffClientOnClose, true);

客户类:
const CI = Components.interfaces, CC = Components.classes, CR = Components.results;
tBirdBiffClient.classID = Components.ID("{5b0bccd0-83b9-11db-9fe1-0800200c9a66}");
tBirdBiffClient.contractID = "@phinecos.cnblogs.com/TBbiff/client;1";
tBirdBiffClient.classDescription = "Biff Client Service";

function tBirdBiffClient()
{
  this.timer = CC["@mozilla.org/timer;1"].getService(CI.nsITimer);//定时器
  this.interval = null;//定时器时间间隔
  this.socketTransport = null;
  this.biffState = null;//邮箱状态
  this.socket = null;//socket对象
  this.input = null;//输入流
  this.port = null;//服务器端口
  this.hostname = null;//服务器主机名称
  this.windowCollection = CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//客户端窗口集合
  this.initialized = false;//是否已经初始化
}

tBirdBiffClient.prototype =
{
  getConnection: function()
  {
    this.closeSocket();//关闭先前的连接
    this.socket = this.socketTransport.createTransport(null, 0, this.hostname, this.port, null);//创建socket连接
    if(!this.socket)
    {
      return;
    }
    var stream = this.socket.openInputStream(CI.nsITransport.OPEN_BLOCKING | CI.nsITransport.OPEN_UNBUFFERED, 0, 0);//打开输入流,类型为阻塞式,无缓冲
    if(!stream)
    {
      this.closeSocket();
      return;
    }
    this.input = CC["@mozilla.org/scriptableinputstream;1"].createInstance(CI.nsIScriptableInputStream);
    if(!this.input)
    {
      this.closeSocket();
      return;
    }
    this.input.init(stream);//初始化输入流
  },
  closeSocket: function()
  {//关闭socket连接
    if(this.input)
    {
      this.input.close(null);
      this.input = null;
    }

    if(this.socket)
    {
      this.socket.close(null);
      this.socket = null;
    }
  },
  currentEventQueue: function()
  {//当前事件队列
    var EQS = CC["@mozilla.org/event-queue-service;1"].getService(CI.nsIEventQueueService);
    return EQS.getSpecialEventQueue(EQS.CURRENT_THREAD_EVENT_QUEUE);
  },
  initialize: function()
  {//初始化客户端
    if(this.initialized)
    {
      return;
    }

    this.getIntervalPref();//获取时间间隔
    this.hostname = this.utility.getHostnamePref();//获取主机名称
    this.port = this.utility.getPortPref();//获取端口
    this.socketTransport = CC["@mozilla.org/network/socket-transport-service;1"].getService(CI.nsISocketTransportService);
    this.getConnection();//创建socket连接
    this.timer.initWithCallback(tBirdBiffCheckMailCallback, 1000, this.timer.TYPE_ONE_SHOT);//启动定时器监听来自服务器的响应
    this.initialized = true;
  },
  updateUi: function(result)
  {//更新客户端UI
    var state;
    switch(result)
    {
      case "":
      {
        state = "offline";
        break;
      }
      case "0":
      {
         state = "noMail";
        break;
      }
      case "1":
      {
        state = "newMail";
        break;
      }
      case "-1":
      {
        state = "error";
        break;
      }
      default:
      {
        state = "weirdness";
        break;
      }
    }
    this.biffState = state;
    state = null;
    var service = CC["@mozilla.org/observer-service;1"].getService(CI.nsIObserverService);
    service.notifyObservers(null, "thunderbirdBiff.uiUpdate", null);
    service = null;
  },
  checkForMail: function()
  {//检查是否有数据到来
    this.timer.initWithCallback(tBirdBiffReadFromServerCallback, 1000, this.timer.TYPE_ONE_SHOT);
  },

  readFromServer: function()
  {//从服务器读取数据
    if(!this.input)
    {//还未初始化输入流
      this.getConnection();
    }
    try
    {
      var result = this.input.read(1);//读取数据
      if(result.length == 1)
      {
        this.updateUi(result);//更新状态
      }
      result = null;
    }
    catch (e)
    {
      this.getConnection();
      this.updateUi("");
    }
    this.timer.initWithCallback(tBirdBiffCheckMailCallback, this.interval, this.timer.TYPE_ONE_SHOT);//设置定时器
  },
}



客户端监听者,负责监视邮箱的状态变化和读取来自服务器端的数据:
const tBirdBiffReadFromServerCallback =
{
  notify: function(timer)
  {//从服务器读取数据
    var client = CC[tBirdBiffClient.contractID].getService(CI.nsISupports).wrappedJSObject;
    client.readFromServer();
    client = null;
  }
}

const tBirdBiffCheckMailCallback =
{
  notify: function(timer)
  {//检查邮箱状态
    var client = CC[tBirdBiffClient.contractID].getService(CI.nsISupports).wrappedJSObject;
    client.checkForMail();
    client = null;
  }
}

      为了测试服务器和客户端,我们使用firefox作为客户端的载体,thunderbird作为服务器端载体,可以看到thunderbird的邮箱状态会定时传给firefox,从而使得后者能随之更新其状态。

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



本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/05/20/1203635.html,如需转载请自行联系原作者
目录
相关文章
|
5月前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
3月前
|
Java 运维
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
53 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创建流程
403 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进程管理模块

热门文章

最新文章

相关实验场景

更多