在Firefox插件中打开套接字连接

3
我想在JavaScript编写的Firefox插件中打开一个套接字连接(发出连接请求,而不是在nsIServerSocket上侦听)。 连接应该是TCP到指定端口的本地主机,并将用于与运行在该计算机上的另一个进程进行通信。
我该如何打开这样的客户端套接字? 我在developer.mozilla.org上找到了诸如nsISocketTransport之类的接口的API文档,但这仍然无法帮助我将这些部分组合在一起。 它甚至没有提到套接字可以用于TCP,因此我甚至不能确定这是否是我需要的接口。 到目前为止,我能找到的只是关于nsIServerSocket的更多信息。 注意:我没有使用add-on SDK,并且直接在引导式插件上工作。
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解决方案,如果您还没有考虑过这个选项,那么这可能值得一试。它肯定比理解原始套接字接口要简单得多。

感谢您的详细回答!您说得对,我不需要一个原始套接字。虽然最初我认为需要,但后来发现我的服务器需要使用HTTP请求,并携带POST负载数据,因此我现在改用nsIHttpChannel。 - Daniel Kraft
然而,未来我可能还需要使用不同的服务器组件,它确实需要原始套接字连接,因此我可能仍然需要使用那些东西。是否有一种方法可以为非HTTP连接使用通用的nsIChannel(或类似)? - Daniel Kraft
是的,它非常相似,但您不需要担心证书。 session.js 中的第101行是一个注释版本,可用于非安全连接:var transport = transportService.createTransport(null, 0, this.address, this.port, null); - Luckyrat
谢谢你的帮助。我正在尝试与其他应用程序通信。比如让IE打开一个新标签页,或者让Excel打开一个新工作表。你有什么关于如何实现这些功能的想法吗? - Blagoh

1

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

特别是这是我现在用来进行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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接