3

I want to open a socket connection (outgoing, not listen on an nsIServerSocket) from within a Firefox add-on in JavaScript. The connection should be TCP to localhost on a specified port, and will be used to communicate with another process running on the machine.

How can I open such a client socket? I found the API documentation for interfaces like nsISocketTransport on developer.mozilla.org, but that still doesn't help me put the pieces together. It doesn't even mention that the socket can be for TCP there, either, so I'm not even 100% sure this is the interface I need. All I could find so far is more about nsIServerSocket. Note: I'm not using the add-on SDK, and work on a bootstrapped add-on directly.

4

2 回答 2

2

你在正确的轨道上。我在 KeeFox 中使用 nsISocketTransport 和 nsISocketTransportService 来启用跨进程通信,但完成图片的是相关的侦听器和回调接口。

该文件应包含一些有用的示例代码:https ://github.com/luckyrat/KeeFox/blob/master/Firefox%20addon/KeeFox/modules/session.js

它在特定端口上打开一个安全的 TCP 连接,定期尝试连接到服务器端口并处理因使用自签名证书而产生的安全异常。

我使用以下接口,但根据具体情况您可能需要稍有不同的接口:

QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2,
                                       Ci.nsIInterfaceRequestor,
                                       Ci.nsIStreamListener,
                                       Ci.nsITransportEventSink,
                                       Ci.nsIOutputStreamCallback])

在这些接口上定义的一些回调包含在第二个文件中,该文件扩展了基本会话对象原型以应用 KeeFox 使用的特定通信协议(JSON-RPC):

https://github.com/luckyrat/KeeFox/blob/master/Firefox%20addon/KeeFox/modules/json.js

https://github.com/luckyrat/KeeFox/blob/master/Firefox%20addon/KeeFox/modules/KF.js创建一些计时器并使用下面的代码开始连接过程,但您可能不需要查看文件非常详细。

this.KeePassRPC = new jsonrpcClient(); // defined in json.js and session.js

// make the initial connection to KeePassRPC
// (fails silently if KeePassRPC is not reachable)
this.KeePassRPC.connect();

// start regular attempts to reconnect to KeePassRPC
this.KeePassRPC.reconnectSoon();

出于兴趣,您是否必须使用原始 TCP 连接?这是 4 年前我创建 KeeFox 时的唯一选择,但我目前正在开发一个 Web Socket 解决方案,因此如果您还没有考虑这个选项,也可能值得考虑。这肯定比了解原始套接字接口要简单得多。

于 2013-07-03T22:21:28.563 回答
1

虽然上面给出的答案非常适合我最初的问题,但我认为发布我现在所做的事情可能会很有趣——我发现服务器不需要原始连接,而是需要 HTTP 请求。为此,一个非常好的信息来源是https://developer.mozilla.org/en-US/docs/Creating_Sandboxed_HTTP_Connections以及nsIHttpChannel从那里链接的更多接口(nsIUploadChannel输入流等)的 API 页面。

特别是,这是我现在用来发出 HTTP 请求并接收其答案的代码:

var ch = NetUtil.newChannel (HTTP_URL);
ch.QueryInterface (Components.interfaces.nsIHttpChannel);
// Here you can set HTTP request headers, like authorization.

var s = Components.classes["@mozilla.org/io/string-input-stream;1"]
        .createInstance (Components.interfaces.nsIStringInputStream);
s.setData (DATA_FOR_SERVER, DATA_FOR_SERVER.length);
ch.QueryInterface (Components.interfaces.nsIUploadChannel);

// I have JSON data, otherwise change the MIME type.
ch.setUploadStream (s, "application/json", -1);
ch.requestMethod = "POST";

s = ch.open ();
var avail = s.available ();
if (avail === 0)
  {
    s.close ();
    throw "Connecting failed.";
  }

var string = NetUtil.readInputStreamToString (s, avail, null);
s.close ();

dump ("Response code: " + ch.responseStatus);
dump ("Response data: " + string);
于 2013-07-04T05:38:45.500 回答