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

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype>

20080506.bmp

Mozilla扩展系列链接:

1浅谈基于Mozilla Thunderbird的扩展开发

2基于Mozilla平台的扩展开发(续)----XPCOM组件篇

3基于Mozilla Thunderbird的扩展开发(三)---如何获取邮件的完整信息

4基于Mozilla Thunderbird的扩展开发(四)---修改源代码实现自动保存附件

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

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

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

本文的目的就是开发一个扩展,展示TCP/IP socket技术在Mozilla扩展开发中的应用。

服务器端主代码:

None.gif consttBirdBiffServerUi =
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.giftBirdBiffServerOnLoad:
function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//启动服务器
InBlock.gif
//removetoavoidduplicateinitialization
InBlock.gif
removeEventListener("load",tBirdBiffServerUi.tBirdBiffServerOnLoad,true);
InBlock.giftBirdBiffCommon.setIconPosition();
//设置图标位置
InBlock.gif
//创建服务器对象并初始化
InBlock.gif
varserver=Components.classes["@phinecos.cnblogs.com/TBbiff/server;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
InBlock.gifserver.initialize();
InBlock.gifserver.addWindow(window);
//保存当前窗口
InBlock.gif
server=null;
ExpandedSubBlockEnd.gif}
,
InBlock.giftBirdBiffServerOnClose:
function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭服务器
InBlock.gif
//removetoavoidduplicateinitialization
InBlock.gif
removeEventListener("close",tBirdBiffServerUi.tBirdBiffServerOnClose,true);
InBlock.gif
InBlock.gif
//移除当前窗口
InBlock.gif
varserver=Components.classes["@dpwhite.com/thunderbirdbiff/server;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
InBlock.gifserver.removeWindow(window);
InBlock.gifserver
=null;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif
None.gifaddEventListener(
" load " ,tBirdBiffServerUi.tBirdBiffServerOnLoad, true );
None.gifaddEventListener(
" close " ,tBirdBiffServerUi.tBirdBiffServerOnClose, true );
None.gif


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

ContractedBlock.gif ExpandedBlockStart.gif 服务器类
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->None.gifconstCI=Components.interfaces,CC=Components.classes,CR=Components.results;
None.gifconstnewMail
="1";
None.gifconstnoMail
="0";
None.gifconstserverError
="9";
None.gif
None.giftBirdBiffServer.classID
=Components.ID("{d2c9b4c6-2851-4d25-8cb6-3d3b037f8e1e}");//组件ID
None.gif
tBirdBiffServer.contractID="@phinecos.cnblogs.com/TBbiff/server;1";
None.giftBirdBiffServer.classDescription
="TBbiffServerService";
None.gif
None.gif
functiontBirdBiffServer()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
this.utility=CC[utilityContractID].getService(CI.nsISupports).wrappedJSObject;//工具类对象
InBlock.gif
this.prefs=CC["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefBranch);
InBlock.gif
this.connections=CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//客户端连接集合
InBlock.gif
this.useAnimation=null;//是否使用动画效果
InBlock.gif
this.mailStatus=noMail;//邮箱状态
InBlock.gif
this.serverSocket=null;//服务器端socket
InBlock.gif
this.port=null;//服务器端口
InBlock.gif
this.windowCollection=CC["@mozilla.org/supports-array;1"].createInstance(CI.nsICollection);//保存的窗口集合
InBlock.gif
this.initialized=false;//是否已经初始化
ExpandedBlockEnd.gif
}

None.gif
None.gifbroadcast:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//向客户端发送数据
InBlock.gif
vardeadConnections=newArray();//已断开的连接
InBlock.gif
varstatus=this.mailStatus;//获取当前邮箱状态
InBlock.gif
varcount=this.connections.Count();//来自客户端的连接数目
InBlock.gif

InBlock.gif
//依次向各个客户端发送服务器的邮箱状态
InBlock.gif
for(vari=0;i<count;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varconnection=this.connections.GetElementAt(i);//来自客户端的连接
InBlock.gif
connection=connection.wrappedJSObject;
InBlock.gif
InBlock.gif
//发送数据给客户端
InBlock.gif
if(!connection.broadcast(status))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifconnection.closeSocket();
//关闭此断开的连接
InBlock.gif
deadConnections[i]=connection;
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdeadConnections[i]
=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifconnection
=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
for(vari=0;i<deadConnections.length;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//移除已经断开的连接
InBlock.gif
if(deadConnections[i]!=null)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.removeConnection(deadConnections[i]);
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifdeadConnections
=null;
InBlock.gifcount
=null;
ExpandedBlockEnd.gif}
,
None.gif
None.gifaddConnection:
function(value)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//加入新的来自客户端的连接
InBlock.gif
this.connections.AppendElement(value);
ExpandedBlockEnd.gif}
,
None.gif
None.gifremoveConnection:
function(value)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//移除连接
InBlock.gif
this.connections.RemoveElement(value);
ExpandedBlockEnd.gif}
,
None.gifgetServerSocket:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//创建服务器端socket,并开始异步监听来自客户端的request
InBlock.gif
this.serverSocket=CC["@mozilla.org/network/server-socket;1"].createInstance(CI.nsIServerSocket);
InBlock.gif
if(!this.serverSocket)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"Unabletogetaserversocket");
ExpandedSubBlockEnd.gif}

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

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.serverSocket=null;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}
,
None.gifcloseServerSocket:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//关闭服务器端socket
InBlock.gif
if(!this.serverSocket)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.serverSocket.close(null);
InBlock.gif
this.serverSocket=null;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}
,
None.gifinitialize:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//初始化服务器
InBlock.gif
if(this.initialized)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//已经初始化过了
InBlock.gif
return;
ExpandedSubBlockEnd.gif}

InBlock.gif
this.port=25501;//设置服务器监听端口
InBlock.gif
this.useAnimation=true;
InBlock.gif
this.getServerSocket();//创建服务器端socket并开始监听
InBlock.gif
this.monitorBiff(true);//监控状态变化
InBlock.gif
this.initialized=true;
ExpandedBlockEnd.gif}
,
None.gifmonitorBiff:
function(isStarting)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//监控邮箱状态变化
InBlock.gif
varsessionService=CC["@mozilla.org/messenger/services/session;1"].getService(CI.nsIMsgMailSession);
InBlock.gif
if(isStarting)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifsessionService.AddFolderListener(tBirdBiffServerBiffStateListener,CI.nsIFolderListener.intPropertyChanged);
//增加监听者
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifsessionService.RemoveFolderListener(tBirdBiffServerBiffStateListener,CI.nsIFolderListener.intPropertyChanged);
//移除监听者
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifsessionService
=null;
ExpandedBlockEnd.gif}
,
None.gif
None.gifcloseAllConnections:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//关闭所有来自客户端的连接
InBlock.gif
varcount=this.connections.Count();
InBlock.gif
for(vari=0;i<count;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varconnection=this.connections.GetElementAt(i);
InBlock.gifconnection
=connection.wrappedJSObject;
InBlock.gifconnection.closeSocket();
InBlock.gifconnection
=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifcount
=null;
InBlock.gif
this.connections.Clear();
ExpandedBlockEnd.gif}
,
None.giffinalize:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//析构函数
InBlock.gif
if(!this.initialized)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
this.closeServerSocket();//关闭服务器端socket
InBlock.gif
this.monitorBiff(false);//移除监听邮箱状态的监听者
InBlock.gif
this.closeAllConnections();//关闭所有来自客户端的连接
ExpandedBlockEnd.gif
}
,
None.gif
None.gifupdateUi:
function(window)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//刷新界面状态
InBlock.gif
varstate;
InBlock.gif
vartip="T-BirdBiff:";
InBlock.gif
varstatus=window.document.getElementById("thunderbird-biff");
InBlock.gif
InBlock.gif
switch(this.mailStatus)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
casenoMail:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//没有新邮件
InBlock.gif
tip+=this.getLocalizedString("noNewMail");
InBlock.gifstate
="noMail";
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
casenewMail:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//有新邮件
InBlock.gif
tip+=this.getLocalizedString("newMail");
InBlock.gif
if(this.useAnimation)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifstate
="newMailAni";//usinggifhereduetoanimation
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifstate
="newMail";
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
default:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//error
InBlock.gif
this.utility.logError("Unexpectedresult:"+this.mailStatus);
InBlock.giftip
=this.getLocalizedString("weirdness");
InBlock.gifstate
="weirdness";
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifstatus.setAttribute(
"tooltiptext",tip);
InBlock.gifstatus.setAttribute(
"biffState",state);
InBlock.giftip
=null;
InBlock.gifstate
=null;
InBlock.gifstatus
=null;
ExpandedBlockEnd.gif}
,
None.gif
None.gifsetMailStatus:
function(value)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//设置邮箱状态
InBlock.gif
if(this.MailStatus==value)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//没有变化
InBlock.gif
return;
ExpandedSubBlockEnd.gif}

InBlock.gif
this.mailStatus=value;
InBlock.gif
//邮箱状态发生改变,逐个窗口通知其更新状态,这些窗口都是服务器端的Observer
InBlock.gif
varserver=CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
InBlock.gif
varwindowCollection=server.getWindowCollection();
InBlock.gif
varcount=windowCollection.Count();
InBlock.gif
for(vari=0;i<count;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varwindow=windowCollection.GetElementAt(i);
InBlock.gif
this.updateUi(window);//更新此窗口状态
InBlock.gif
window=null;
ExpandedSubBlockEnd.gif}

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

InBlock.gifwindowCollection
=null;
InBlock.gifcount
=null;
InBlock.gifserver
=null;
ExpandedBlockEnd.gif}
,
None.gif
None.gifcheck:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//检查服务器邮箱状态
InBlock.gif
tBirdBiffServerBiffStateListener.clearIntervalTimeout();//清除此前的定时器
InBlock.gif
this.setMailStatus(this.checkServers());//实际的检查动作
ExpandedBlockEnd.gif
}
,
None.gif
None.gifcheckServers:
function()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifconstbiffShowsMailReady
=0;
InBlock.gif
//帐户管理器
InBlock.gif
varaccountManager=CC["@mozilla.org/messenger/account-manager;1"].getService(CI.nsIMsgAccountManager);
InBlock.gif
if(accountManager)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//获取此用户的所有服务器
InBlock.gif
varservers=accountManager.allServers;
InBlock.gif
varnumServers=servers.Count();
InBlock.gif
InBlock.gif
for(vari=0;i<numServers;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varserver=servers.GetElementAt(i).QueryInterface(CI.nsIMsgIncomingServer);
InBlock.gif
InBlock.gif
if(server.rootFolder!=server.rootMsgFolder)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
continue;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(server.type!="pop3"&&server.type!="imap")
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(server==accountManager.localFoldersServer)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"tBirdBiffServer.checkServers"+server.prettyName+"appearstobeLocalFolders");
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"Non-pop3,IMAP,orLocalFoldersserverfound.Typeis"+server.type+",nameis"+server.prettyName);
InBlock.gif
continue;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
if(server.biffState==biffShowsMailReady)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//有新邮件到来
InBlock.gif
server=null;
InBlock.gifservers
=null;
InBlock.gifnumServers
=null;
InBlock.gifaccountManager
=null;
InBlock.gif
returnnewMail;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
//没有新邮件
InBlock.gif
servers=null;
InBlock.gifnumServers
=null;
InBlock.gifaccountManager
=null;
InBlock.gif
returnnoMail;
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifaccountManager
=null;
InBlock.gif
this.utility.logError("Unabletogetaccountmanager");
InBlock.gif
returnserverError;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifaccountManager
=null;
InBlock.gif
returnserverError;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}
,
None.gif
None.gif来自客户端的连接对象类:
None.gif
functiontBirdBiffServerConnection()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
this.wrappedJSObject=this;
ExpandedBlockEnd.gif}

None.gif
None.giftBirdBiffServerConnection.prototype
=
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifsocket:
null,//客户端对应的socket
InBlock.gif
outputStream:null,//输出流
InBlock.gif

InBlock.gifsetSocket:
function(value)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//保存来自客户端的socket连接
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.outputStream=value.openOutputStream(CI.nsITransport.OPEN_BLOCKING|CI.nsITransport.OPEN_UNBUFFERED,0,0);//打开输出流,类型为阻塞型,无缓冲区
ExpandedSubBlockEnd.gif
}

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(!this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
this.socket=value;
InBlock.gif
returntrue;
ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifcloseSocket:
function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭来自客户端的socket
InBlock.gif
if(this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭输出流
InBlock.gif
this.outputStream.close(null);
InBlock.gif
this.outputStream=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(this.socket)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭对应的socket
InBlock.gif
this.socket.close(null);
InBlock.gif
this.socket=null;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifbroadcast:
function(value)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//向客户端发送数据
InBlock.gif
if(!this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.closeSocket();
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.outputStream.write(value,value.length);//发送数据
ExpandedSubBlockEnd.gif
}

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.closeSocket();
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
returntrue;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif


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

None.gif function tBirdBiffServerConnection()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
this.wrappedJSObject=this;
ExpandedBlockEnd.gif}

None.gif
None.giftBirdBiffServerConnection.prototype
=
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifsocket:
null,//客户端对应的socket
InBlock.gif
outputStream:null,//输出流
InBlock.gif

InBlock.gifsetSocket:
function(value)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//保存来自客户端的socket连接
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.outputStream=value.openOutputStream(CI.nsITransport.OPEN_BLOCKING|CI.nsITransport.OPEN_UNBUFFERED,0,0);//打开输出流,类型为阻塞型,无缓冲区
ExpandedSubBlockEnd.gif
}

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(!this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
this.socket=value;
InBlock.gif
returntrue;
ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifcloseSocket:
function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭来自客户端的socket
InBlock.gif
if(this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭输出流
InBlock.gif
this.outputStream.close(null);
InBlock.gif
this.outputStream=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(this.socket)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//关闭对应的socket
InBlock.gif
this.socket.close(null);
InBlock.gif
this.socket=null;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifbroadcast:
function(value)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//向客户端发送数据
InBlock.gif
if(!this.outputStream)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.closeSocket();
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.outputStream.write(value,value.length);//发送数据
ExpandedSubBlockEnd.gif
}

InBlock.gif
catch(e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.closeSocket();
InBlock.gif
returnfalse;
ExpandedSubBlockEnd.gif}

InBlock.gif
returntrue;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif
None.gifconsttBirdBiffServerSocketListener
=
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifonSocketAccepted:
function(serverSocket,clientSocket)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//接受来自客户端的请求
InBlock.gif
varconnection=newtBirdBiffServerConnection();//新建一个连接对象
InBlock.gif
//保存当前接收的连接
InBlock.gif
if(connection.setSocket(clientSocket))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varserver=CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
InBlock.gif
//向客户端发送数据
InBlock.gif
if(connection.broadcast(server.getMailStatus()))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifserver.addConnection(connection);
//保存连接对象到在线连接集合中
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"connectionNOTadded");
ExpandedSubBlockEnd.gif}

InBlock.gifserver
=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"Creatingconnectionfailed");
ExpandedSubBlockEnd.gif}

InBlock.gifconnection
=null;
ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifonStopListening:
function(serverSocket,status)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//服务器停止监听
InBlock.gif
alert("Serversockethasstoppedlistening");
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif


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

None.gif consttBirdBiffServerBiffStateListener =
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.giftimer:
null,//定时器,负责定时检查邮箱状态
InBlock.gif
clearIntervalTimeout:function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//清除定时器
InBlock.gif
if(this.timer)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.timer=CC["@mozilla.org/timer;1"].getService(CI.nsITimer);
InBlock.gif
this.timer.cancel();
InBlock.gif
this.timer=null;
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"Timerisnull");
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}
,
InBlock.gif
InBlock.gifOnItemIntPropertyChanged:
function(item,property,oldValue,newValue)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//参见Thunderbird源代码,此函数负责监视各个文件夹的属性变化,当有新邮件到来时,property的值为“BiffState”
InBlock.gif
if(property.toString()!="BiffState")
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return;
ExpandedSubBlockEnd.gif}

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

ExpandedBlockEnd.gif}

None.gif

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

None.gifconsttBirdBiffServerCheckCallback =
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//定时检查邮箱状态的处理函数
InBlock.gif
notify:function(timer)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
varserver=CC[tBirdBiffServer.contractID].getService(CI.nsISupports).wrappedJSObject;
InBlock.gifserver.check();
//检查邮箱状态
InBlock.gif
server=null;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif


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

Reference:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值