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

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

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

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

来源: 发布时间:星期四, 2009年1月15日 浏览:21次 评论:0
  最近遇到这样个需求:在我们MFC中控制Thunderbird拿到这个奇怪需求后有了这么几个想法:1)用全局钩子试着勾住Thunderbird可细想好像不对2)用spy探查点击Thunderbird各个菜单按钮时触发事件总归是win32平台上跑归根到底还是事件触发从理论上说应该是可以在我们自己MFC中模拟目标各个事件触发

  但接触到Mozilla方面知识后放弃了上面想法改用通信来实现此需求来Thunderbird源代码可以自行修改因此可以加入些代码使的成为个类似HTTP服务器服务器端 2来使用进行连接和语言无关因此C可以和javascript完成通信但缺点也很明显要占用端口只涉及到本地机器通信却使用了这样网络通信机制

  先来介绍下完成这个功能用到基本知识:由于输入流基接口nsIInputStream没有提供任何从javascript中读取数据思路方法而只能在C中读取因此我们必须使用个可脚本化输入流来对其进行包装这个可脚本化输入流实现了nsIScriptableInputStream接口

  当然也可以使用其他流类型比如为了读取 2进制数据我们可以使用nsIBinaryInputStream反正在javascript中你总得以其他形式流来包装基流

  在Mozilla中网络数据读和写是在个单独线程中进行中读数据是异步这就意味着只要中有数据存在就在后台读取数据会收到数据可读通知信息这就意味着我们需要创建个监听者来监听这个信息

  对于异步读取数据我们还需要创建个输入流Pump,的所以Mozilla选择“泵”这个名称是当有数据存在时它就发送小块数据给监听者这个Pump实现了nsIInputStreamPump接口这个接口继承自nsIRequest,后者提供了暂停连接和特定缓存Cache行为(这些用不上但像HTTP这样构建在高层次应用会用得上)

  pump.asyncRead(dataListener,null);

  asyncRead用来给Pump对象设置个监听者当有数据到来或连接关闭时监听者就会被监听者对象应该实现nsIStreamListener接口这个接口有个思路方法onDataAvailable,当有额外数据可读时就会被此接口继承自nsIRequestObserver这个接口有两个思路方法onStartRequestonStopRequest这两个思路方法在输入流开始和结束时分别被因此这3个思路方法都应该实现

  下面是客户端代码使用最简单阻塞式TCP连接:

void CClientTestDlg::OnSend
{//发送按钮
  UpdateData;
  (str.IsEmpty)
  {
    list.InsertString(0,"发送串不能为空");
    ;
  }
  //strcpy(msg.msg,(LPCTSTR)str);
  char szText[1024];
  strcpy(szText,(LPCTSTR)str);
  SOCKET = ::(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  (INVALID_SOCKET)
  {
    list.InsertString(0,"创建发生");
    ;
  }
  SOCKADDR_IN servAddr;
  servAddr.sin_family = AF_INET;
  servAddr.sin_port = htons(25501);
  servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
  (::connect(,(sockaddr*)&servAddr,(servAddr))-1)
  {
    list.InsertString(0,"连接服务器发生");
    ;
  }
  (::send(,szText,strlen(szText),0) SOCKET_ERROR)//  recv(ServerSocket,buf,(buf),0);
  {
    list.InsertString(0,"发送数据发生");
    ;
  }
   sRecv = SOCKET_ERROR;
  char buffer[1024];
  mem(buffer,0,1024);
  sRecv = recv( , buffer, 1024, 0 );
  DWORD dwerr = WSAGetLastError;
  CString str;
  str.Format("%s",buffer);
  list.InsertString(0,str);
  ::close();
}


  服务器端代码通过修改Thunderbird源代码使的成为个类似HTTP服务器服务器端

//***************************************************************************
//Author: phinecos
//Date : 2008/5/19
//Description:服务器监听对象
//Contact:[email protected]
//***************************************************************************
//服务器端对象
  
const CI = Components.erfaces, CC = Components.es, CR = Components.results;
  
var gServer = null;//服务器对象
var gUtility = null;//工具类对象
//var gConnection = null;//客户端连接对象
  
function tBirdBfServerOnLoad
{//启动监听服务器
  
  try
  {
    gUtility = tBirdBfUtility;//新建日志对象
    gUtility.initialize;
     gUtility.log("tBirdBfServerUi.tBirdBfServerOnLoad", "Thunderbird bf server loaded");
  
    gServer = tBirdBfServer;//新建服务器对象
    gServer.initialize;//化服务器端
    gUtility.log("tBirdBfServerOnLoad","start server");
  }
  catch(err)
  {
     gUtility.log("tBirdBfServerOnLoad","start server failed");
  }
}
  
function tBirdBfServerOnClose
{//关闭服务器  
  gUtility.log("tBirdBfServerOnClose","close server");
  gServer.finalize;
  gServer = null;
  gUtility = null;
}
  
function tBirdBfServer
{
 this.serverSocket = null;//服务器端
 this.port = null;//服务器端口
 this.initialized = false;
 gUtility.log("tBirdBfServer constructor","construct ok");
}
  
tBirdBfServer.prototype =
{
 getServerSocket: function
 {//创建服务器端
  this.serverSocket = CC["@mozilla.org/network/server-;1"].createInstance(CI.nsIServerSocket);
  (!this.serverSocket)
  {
   gUtility.log("tBirdBfServer.getServerSocket","Unable to get a server ");
  }
  
  {
   try
   {
    this.serverSocket.init(this.port, false, -1);//,绑定到端口port上
    this.serverSocket.asyncListen(tBirdBfServerSocketListener);//开始异步监听
    gUtility.log("tBirdBfServer.getServerSocket","Server established");
   }
   catch(e)
   {
     gUtility.log("tBirdBfServer.getServerSocket, Server established error");
     this.serverSocket = null;
   }
  }
 },
  
 closeServerSocket: function
 {//关闭服务器端
  (!this.serverSocket)
  {
   this.serverSocket.close(null);
   this.serverSocket = null;
  }
 },
  
 initialize: function
 {
  (this.initialized)
  {
   ;
  }
  
  this.port = 25501;//获取端口号
  gUtility.log("tBirdBfServer.initialize","port is: "+this.port);
  this.getServerSocket;//创建服务器端
  this.initialized = true;
    gUtility.log("tBirdBfServer.initialize","initialize ok!");
 },
 finalize: function
 {//退出
  (!this.initialized)
  {
   ;
  }
  this.closeServerSocket;//关闭服务器端
  gUtility.log("tBirdBfServer.finalize","server Finalized");
 },
  
}
 var listener =
 {
  finished : function(data)
  {//数据读取完毕
   ParseCommand(data);//解析命令字
  }
 }
  
const tBirdBfServerSocketListener =
{
 onSocketAccepted: function(serverSocket, clientSocket)
 {//接受来自客户端请求
   gUtility.log("tBirdBfServerSocketListener.onSocketAccepted","Got a connection from: " + clientSocket.host + ":" + clientSocket.port);
   var outputData = "Ok,server get your command";
   var outstream = clientSocket.openOutputStream(0,0,0);
   outstream.write(outputData,outputData.length);
   try
   {
     //打开输入流
     var stream = clientSocket.openInputStream(0,0,0);
     var instream = Components.es["@mozilla.org/scriptableinputstream;1"].createInstance(Components.erfaces.nsIScriptableInputStream);
     instream.init(stream);
    
    var dataListener =
    {
     data : "",//来自客户端数据
     onStartRequest: function(request, context){},
     onStopRequest: function(request, context, status){
      instream.close;
      outstream.close;
      listener.finished(this.data);
     },
     onDataAvailable: function(request, context, inputStream, off, count){
      this.data instream.read(count);
     },
    };
    var pump = Components.es["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.erfaces.nsIInputStreamPump);
    pump.init(stream, -1, -1, 0, 0, false);
    pump.asyncRead(dataListener,null);
  }
  catch(err)
  {
    gUtility.log("tBirdBfServerConnection.Socket",e);
      false;
  }
 },
 onStopListening: function(serverSocket, status)
 {//服务器端停止监听
  gUtility.log("tBirdBfServerSocketListener.onStopListening","Server has stopped listening");
 }
}


0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: