ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ ОБНОВЛЕНИЕ № 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 устарел?
Я тестирую с Firefox 3.6.6.
Я был бы очень признателен за ответ.Возможно, вы могли бы указать на хороший пример использования Sockets в компоненте XPCOM.Я не видел много таких вокруг.
ОБНОВЛЕНИЕ
Я только что понял, что раньше это работало, так что теперь я думаю, что мой компонент консоли ломает его.Я понятия не имею, как это связано.Но если я не использую этот компонент, сокеты работают нормально.
Вот код моего компонента консоли.Я постараюсь выяснить, что не так и почему это мешает, и позже опубликую свои выводы.Скорее всего, я делаю здесь что-то ужасно неправильное, чтобы вызвать ошибки сегментации с моим javascript =)
Voodoo ..
components / 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);
}
I 'используя этот компонент так:
console = Cc["@ed.ac.uk/poly/console;1"].getService().wrappedJSObject;
console.log("something");
И это ломает сокеты: -S =)
ОБНОВЛЕНИЕ # 2 Хорошо, если кто-то заинтересован в проверке этогоЯ бы очень признателен за это + Я думаю, что это, скорее всего, какая-то ошибка (ошибка сегмента из javascript не должна возникать) Я сделал минимальную версию расширения, которая вызывает проблему, вы можете установить ее отсюда:
http://dl.dropbox.com/u/645579/segfault.xpi
Важной частью является chrome / content / main.js:
http://pastebin.com/zV0e73Na
Как мой друг и яМожно воспроизвести ошибку, запустив Firefox, после чего должно появиться новое окно с надписью «Открыто гнездо на 9999».Подключитесь с помощью "telnet localhost 9999" и отправьте несколько сообщений.После 2-6 сообщений вы получаете одно из следующих сообщений в терминале, где запущен Firefox:
1 (чаще всего)
Ошибка сегментации
2 (видел несколько раз)
firefox-bin: фатальная ошибка ввода-вывода 11 (ресурс временно недоступен) на X-сервере: 0,0.
3 (видел пару раз)
GLib-ERROR **: /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) 'не выполнено.Прервано </p>
Если вам нужна дополнительная информация или вы можете указать мне, где разместить сообщение об ошибке: - / Я буду рад это сделать.
Я знаю, что это только одна измного ошибок ... но, возможно, у вас есть представление о том, что я должен делать по-другому, чтобы избежать этого?Я хотел бы использовать эту мою «консоль» таким образом.
Я попробую сделать это с буфером / сбросом / попыткой / поймать, как предлагают люди, но мне интересно, поймает ли попытка / пойматьСег ошибки ...