在上一篇《基于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,如需转载请自行联系原作者