javascript – Firefox插件之间的消息
作者:互联网
我正在尝试在两个或多个插件之间实现客户端 – 服务器通信,其中每个插件同时是服务器和客户端.我使用nsIServerSocket作为客户端部分的服务器部分和websockets.这是代码:
function startServer(port) {
var listener = {
onSocketAccepted: function(serverSocket, transport) {
console.log("Accepted connection on " + transport.host + ":" + transport.port);
var input = transport.openInputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);//.QueryInterface(Ci.nsIAsyncInputStream);
var output = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
var sin = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
try{
sin.init(input);
var readBytes = sin.available();
var request = '';
request = sin.read(readBytes);
console.log('Received: ' + request);
//getUrl(request);
output.write("yes", "yes".length);
output.flush();
}
finally{
sin.close();
input.close();
output.close();
}
}
}
try{
var serverSocket = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
serverSocket.init(port, true, 5);
console.log("Opened socket on " + serverSocket.port);
serverSocket.asyncListen(listener);
}catch(e){
console.log(e);
}
}
对于服务器部分,以及客户端部分的以下内容:
var address="ws://otherAddress:1234";// + port;
var window = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService)
.hiddenDOMWindow;
ws = new window.WebSocket(address);
try{
ws.onmessage = function () {
};
ws.onopen = function(){
console.log("connection opened");
// Web Socket is connected. You can send data by send() method
ws.send("lol ");
};
ws.onclose = function() {
// websocket is closed. };
console.log("websocket is closed");
}
}catch(evt){
console.log(evt.data);
}
客户端代码在用户单击按钮时启动….此代码部分工作,因为从控制台我看到当用户单击按钮时,服务器接收连接打开,但我无法收到消息…. ..任何人可以帮助我吗?谢谢
更新1
我在控制台中看到的消息是这样的:
"Received: GET / HTTP/1.1
Host: localhost:1234
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: resource://gre-resources
Sec-WebSocket-Key: zh/EpJRRsOAgLfPIbI1EDg==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
更新2
在nmaier和IvyLynx回答之后(非常感谢!!),我修改了我的代码插入一个完整的“ServerSocket”实现(主要是因为将来我也将传递二进制数据).这是localhost案例的代码:
var {Cc, Ci, Cu, Cr, components} = require("chrome");
// the thread manager can be important when using asynchronous mode
var thread_manager = Cc["@mozilla.org/thread-manager;1"].getService();
var socket_service = Cc["@mozilla.org/network/socket-transportservice;1"].getService(Ci.nsISocketTransportService);
// make some constructors so we don't have to worry about this later
var socket = Cc["@mozilla.org/network/serversocket;1"].createInstance(Ci.nsIServerSocket);
// set the second argument to false if you want it to listen
// to connections beyond the computer the extension runs on
socket.init(-1, true, -1);
var output_stream_bin = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
var input_stream_bin = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
// this is so we can easily instantiate nsIInputStreamPump, which allows us to read input streams properly
var input_stream_pump_c = Cc["@mozilla.org/network/input-stream-pump;1"];
var input_stream_base, input_stream_async_c, input_stream_async, recieved_bytes, recieved_total, input_stream_pump;
var output_stream_base, output_stream_async_c, output_stream_async, generalStream;
var client, client_input_stream, client_output_stream, client_input_stream_pump;
var data_to_send = "hi hi"; // this holds what we want to send
var socket_transport = socket_service.createTransport(null, 0, "localhost", socket.port, null);
var socket_listener = {
onSocketAccepted: function(socket, transport){
client = transport;
client_input_stream = client.openInputStream(0, 0, 0);
client_output_stream = client.openOutputStream(0, 0, 0);
client_output_stream.QueryInterface(Ci.nsIAsyncOutputStream);
generalStream = client_output_stream;
client_input_stream_pump[this_transport] = input_stream_pump_c.createInstance(Ci.nsIInputStreamPump);
client_input_stream_pump[this_transport].init(client_input_stream, -1, -1, 0, 0, false);
client_input_stream_pump[this_transport].asyncRead(socket_reader, socket);
},
onStopListening: function(socket, status){
}
};
socket.asyncListen(socket_listener);
// this guy will get called when we're ready to send data
var output_stream_callback = {
onOutputStreamReady: function(stream){
output_stream_bin.setOutputStream(stream);
output_stream_bin.writeBytes(data_to_send, data_to_send.length);
data_to_send = "";
}
};
var socket_reader = {
onDataAvailable: function(request, context, stream, offset, count){
input_stream_bin.setInputStream(stream);
if(input_stream_bin.available() > 0){
recieved_bytes = input_stream_bin.readByteArray(count);
recieved_total = "";
// this loop converts bytes to characters
// if you don't need to pass binary data around
// you can just use nsIScriptableInputStream instead of
// nsIBinaryInputStream and skip this
for (var i = 0; i < recieved_bytes.length; i++){
recieved_total += String.fromCharCode(recieved_bytes[i]);
}
console.log("Received " + recieved_total)
}else{
stream.close();
}
},
onStartRequest: function(request, context){
},
onStopRequest: function(request, context, status){
}
};
require("sdk/widget").Widget({
id: "mozilla-link",
label: "Mozilla website",
contentURL: data.url("icon.png"),
onClick: listTabs
});
function listTabs() {
//console.log(client_output_stream);
generalStream.asyncWait(output_stream_callback,0,0,thread_manager.mainThread);
};
问题是generalStream变量.当用户点击扩展图标时我调用asyncWait方法,但我也用其他方法插入调用.每个generalStream.asyncWait都会引发以下问题(实际上,在执行扩展时,实际存在配置文件的路径):
console.error: client:
Message: TypeError: generalStream is undefined
Stack:
listTabs@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NP
aadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/lo
ader.js -> resource://jid1-exo2npaaditkqg-at-jetpack/client/lib/main.js:742
_emitOnObject@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2N PaadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/l
oader.js -> resource://gre/modules/commonjs/sdk/deprecated/events.js:153
_emit@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NPaadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/deprecated/events.js:123 _onEvent@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NPaadi
Tkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/widget.js:278
WidgetView__onEvent@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NPaadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/widget.js:426
WC_addEventHandlers/listener/<@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NPaadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/widget.js:884
notify@resource://gre/modules/XPIProvider.jsm -> jar:file:///.../extensions/jid1-exo2NPaadiTkqg@jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/timers.js:40
解决方法:
nsISocketServer实现了一个简单的TCP /绑定服务器,但没有实现websocket协议.
>您需要在服务器套接字中自己实现the websocket protocol(包括HTTP / 1.1升级)
>或使用原始TCP套接字(通过nsISocketTransportService的nsISocketTransports).
鉴于原始TCP套接字通常是一个混乱的处理,你需要在此基础上实现一些简单的交换协议,我猜在服务器套接字中实现websocket协议的第一个选项会更容易(至少,你可以免费获得客户端实现.
PS:阻止模式是一个坏主意,因为它可能会长时间阻止UI线程.
PS:显然,有人implemented the websocket protocol already in coffee script和其他人(来自Add-on SDK团队)也实现了它in (what appears to be some form of :p) Javascript(虽然后者几乎不是自包含且难以阅读/喘气).
编辑我好奇并写了a stand-alone JS code module WebSocket server,这似乎主要是工作. :p
标签:javascript,plugins,firefox-addon,firefox-addon-sdk,xpcom 来源: https://codeday.me/bug/20190528/1173330.html