gpt4 book ai didi

firefox - 在 XPCOM 组件(Firefox 扩展)中使用套接字(nsIServerSocket)(套接字 + 新窗口 = 段错误)

转载 作者:行者123 更新时间:2023-12-03 11:52:36 27 4
gpt4 key购买 nike

如果您对此问题感兴趣,请阅读下面的更新 #2 ;)

假设我将此代码放入我的扩展程序的 JS 中。

var reader = {
onInputStreamReady : function(input) {
var sin = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
sin.init(input);
sin.available();
var request = '';
while (sin.available()) {
request = request + sin.read(512);
}
console.log('Received: ' + request);
input.asyncWait(reader,0,0,null);
}
}
var listener = {
onSocketAccepted: function(serverSocket, clientSocket) {
console.log("Accepted connection on "+clientSocket.host+":"+clientSocket.port);
input = clientSocket.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
output = clientSocket.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
input.asyncWait(reader,0,0,null);
}
}
var serverSocket = Cc["@mozilla.org/network/server-socket;1"].
createInstance(Ci.nsIServerSocket);
serverSocket.init(-1, true, 5);
console.log("Opened socket on " + serverSocket.port);
serverSocket.asyncListen(listener);

然后我运行 Firefox 并通过 telnet 连接到套接字
telnet localhost PORT

我发送了 5 条消息,它们被打印出来,但是当我尝试发送第 6 条消息时,我得到了
firefox-bin: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

更糟糕的是,当我尝试将相同的代码放入 XPCOM 组件中时(因为那是我真正需要它的地方),在我尝试通过 telnet 发送消息后,我得到
Segmentation fault

或者有时
GLib-ERROR **: /build/buildd/glib2.0-2.24.1/glib/gmem.c:137: failed to allocate 32 bytes
aborting...
Aborted

打印到我启动 Firefox 的终端。

这真的很奇怪。你能发现我粘贴的代码有问题吗?或者我的 Firefox/系统有问题,或者 nsIServerSocket 接口(interface)是否已弃用?

我正在使用 Firefox 3.6.6 进行测试。

我真的很感激一些答案。也许你可以给我指出一个在 XPCOM 组件中使用 Sockets 的好例子。我周围很多人都没见过。

更新

我刚刚意识到它曾经可以工作,所以现在我认为我的控制台
组件破坏它。我不知道这有什么关系。但如果我
不要使用这个组件,套接字工作正常。

这是我的控制台组件的代码。我会试着弄清楚
出了什么问题以及为什么会干扰,我稍后会发布我的发现。
可能我在这里做错了什么导致分割
我的 javascript 有问题 =)

巫毒教..

组件/Console.js:
const Cc = Components.classes; 
const Ci = Components.interfaces;
const Cr = Components.results;
Console.prototype = (function() {
var win;
var initialized = false;
var ready = false;
var _log = function(m, level, location) {
if (initialized&&ready) {
var prefix = "INFO: ";
switch (level) {
case "empty":
prefix = ""
break;
case "error":
prefix = "ERORR: "
break;
case "warning":
prefix = "WARNING: "
break;
}
win.document.getElementById(location).value =
win.document.getElementById(location).value + prefix + m + "\n";
win.focus();
} else if (initialized&&!ready) {
// Now it is time to create the timer...
var timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
// ... and to initialize it, we want to call
event.notify() ...
// ... one time after exactly ten second.
timer.initWithCallback(
{ notify: function() { log(m); } },
10,
Components.interfaces.nsITimer.TYPE_ONE_SHOT
);
} else {
init();
log(m);
}
}
var log = function(m, level) {
_log(m, level, 'debug');
}
var poly = function(m, level) {
_log(m, "empty", 'polyml');
}
var close = function() {
win.close();
}
var setReady = function() {
ready = true;
}
var init = function() {
initialized = true;
var ww = Components.classes["@mozilla.org/embedcomp/window-
watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
win = ww.openWindow(null, "chrome://polymlext/content/
console.xul",
"console", "chrome,centerscreen,
resizable=no", null);
win.onload = setReady;
return win;
}
return {
init: init,
log : log,
poly : poly,
}
}());

// turning Console Class into an XPCOM component
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function Console() {
this.wrappedJSObject = this;
}

prototype2 = {
classDescription: "A special Console for PolyML extension",
classID: Components.ID("{483aecbc-42e7-456e-b5b3-2197ea7e1fb4}"),
contractID: "@ed.ac.uk/poly/console;1",
QueryInterface: XPCOMUtils.generateQI(),
}

//add the required XPCOM glue into the Poly class
for (attr in prototype2) {
Console.prototype[attr] = prototype2[attr];
}

var components = [Console];
function NSGetModule(compMgr, fileSpec) {
return XPCOMUtils.generateModule(components);
}

我正在使用这样的组件:
console = Cc["@ed.ac.uk/poly/console;1"].getService().wrappedJSObject; 
console.log("something");

这打破了套接字:-S =)

更新 #2
好的,如果有人有兴趣检查这件事,我真的会
欣赏它+我认为这可能是某种错误(Seg fault
来自javascript不应该发生)
我已经制作了导致问题的扩展的最小版本,
你可以从这里安装它:

http://dl.dropbox.com/u/645579/segfault.xpi

重要的部分是 chrome/content/main.js:

http://pastebin.com/zV0e73Na

我和我的 friend 重现错误的方法是启动
firefox,然后应该会出现一个新窗口,上面写着“Opened socket on
9999”。使用“telnet localhost 9999”连接并发送一些消息。
在 2-6 条消息后,您会在
启动 Firefox 的终端:

1(最常见)

分段故障

2(多次看到)

firefox-bin: 致命 IO 错误 11 (资源暂时不可用) on
X
服务器:0.0。

3(看过几次)

GLib-错误**:/build/buildd/glib2.0-2.24.1/glib/gmem.c:137:失败

分配 32 个字节
中止...
中止

4(看过一次)

firefox-bin:../../src/xcb_io.c:249:process_responses:断言
`(((long) (dpy->last_request_read) - (long) (dpy->request)) <= 0)'
失败的。
中止

如果您需要更多信息或可以指出我在哪里发布错误
报告:-/我很乐意这样做。

我知道这只是众多错误之一......但也许你有一个
我应该怎么做才能避免这种情况的想法?我想
以这种方式使用我的那个“控制台”。

我会按照人们的建议尝试使用 buffer/flushing/try/catch 来做,但我想知道 try/catch 是否会捕获 Seg 错误......

最佳答案

这是一个线程问题。回调 onInputStreamReady 恰好在不同的线程中执行,并且只允许从主线程访问 UI/DOM。
解决方案非常简单:

改变

input.asyncWait(reader,0,0,null);


var tm = Cc["@mozilla.org/thread-manager;1"].getService();
input.asyncWait(reader,0,0,tm.mainThread);

关于firefox - 在 XPCOM 组件(Firefox 扩展)中使用套接字(nsIServerSocket)(套接字 + 新窗口 = 段错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3176442/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com