如何在 Firefox 附加组件中向子进程发送消息,例如 Chrome 本机消息
How to message child process in Firefox add-on like Chrome native messaging
我正在尝试模仿 Chrome 的 native messaging feature using Firefox's add-on SDK. Specifically, I'm using the child_process module along with the emit method 与 python 子进程通信。
我能够成功地向子进程发送消息,但是我无法将消息发送回附加组件。 Chrome 的本地消息传递功能使用 stdin/stdout。双向每条消息的前 4 个字节表示后续消息的字节大小,因此接收方知道要读取多少。这是我目前所拥有的:
附加到子进程
var utf8 = new TextEncoder("utf-8").encode(message);
var latin = new TextDecoder("latin1").decode(utf8);
emit(childProcess.stdin, "data", new TextDecoder("latin1").decode(new Uint32Array([utf8.length])));
emit(childProcess.stdin, "data", latin);
emit(childProcess.stdin, "end");
来自插件的子进程(Python)
text_length_bytes = sys.stdin.read(4)
text_length = struct.unpack('i', text_length_bytes)[0]
text = sys.stdin.read(text_length).decode('utf-8')
加载项的子进程
sys.stdout.write(struct.pack('I', len(message)))
sys.stdout.write(message)
sys.stdout.flush()
来自子进程的附加组件
这就是我挣扎的地方。当长度小于 255 时,我可以使用它。例如,如果长度为 55,则可以使用:
childProcess.stdout.on('data', (data) => { // data is '7' (55 UTF-8 encoded)
var utf8Encoded = new TextEncoder("utf-8).encode(data);
console.log(utf8Encoded[0]); // 55
}
但是,正如我所说,它并不适用于所有数字。我确定我必须用 TypedArrays 做点什么,但我正在努力将所有东西放在一起。
也许这与这个问题类似:
Chrome native messaging doesn't accept messages of certain sizes (Windows)
Windows-only: Make sure that the program's I/O mode is set to O_BINARY. By default, the I/O mode is O_TEXT, which corrupts the message format as line breaks (\n = 0A) are replaced with Windows-style line endings (\r\n = 0D 0A). The I/O mode can be set using __setmode.
这里的问题是,Firefox 默认尝试将标准输出读取为 UTF-8 流。由于 UTF-8 不使用完整的第一个字节,因此您会得到损坏的字符,例如 255。解决方案是告诉 Firefox 以二进制编码读取,这意味着您稍后必须手动解析实际的消息内容。
var childProcess = spawn("mybin", [ '-a' ], { encoding: null });
你的监听器会像
一样工作
var decoder = new TextDecoder("utf-8");
var readIncoming = (data) => {
// read the first four bytes, which indicate the size of the following message
var size = (new Uint32Array(data.subarray(0, 4).buffer))[0];
//TODO: handle size > data.byteLength - 4
// read the message
var message = decoder.decode(data.subarray(4, size));
//TODO: do stuff with message
// Read the next message if there are more bytes.
if(data.byteLength > 4 + size)
readIncoming(data.subarray(4 + size));
};
childProcess.stdout.on('data', (data) => {
// convert the data string to a byte array
// The bytes got converted by char code, see https://dxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/sdk/system/child_process/subprocess.js#357
var bytes = Uint8Array.from(data, (c) => c.charCodeAt(0));
readIncoming(bytes);
});
我正在尝试模仿 Chrome 的 native messaging feature using Firefox's add-on SDK. Specifically, I'm using the child_process module along with the emit method 与 python 子进程通信。
我能够成功地向子进程发送消息,但是我无法将消息发送回附加组件。 Chrome 的本地消息传递功能使用 stdin/stdout。双向每条消息的前 4 个字节表示后续消息的字节大小,因此接收方知道要读取多少。这是我目前所拥有的:
附加到子进程
var utf8 = new TextEncoder("utf-8").encode(message);
var latin = new TextDecoder("latin1").decode(utf8);
emit(childProcess.stdin, "data", new TextDecoder("latin1").decode(new Uint32Array([utf8.length])));
emit(childProcess.stdin, "data", latin);
emit(childProcess.stdin, "end");
来自插件的子进程(Python)
text_length_bytes = sys.stdin.read(4)
text_length = struct.unpack('i', text_length_bytes)[0]
text = sys.stdin.read(text_length).decode('utf-8')
加载项的子进程
sys.stdout.write(struct.pack('I', len(message)))
sys.stdout.write(message)
sys.stdout.flush()
来自子进程的附加组件
这就是我挣扎的地方。当长度小于 255 时,我可以使用它。例如,如果长度为 55,则可以使用:
childProcess.stdout.on('data', (data) => { // data is '7' (55 UTF-8 encoded)
var utf8Encoded = new TextEncoder("utf-8).encode(data);
console.log(utf8Encoded[0]); // 55
}
但是,正如我所说,它并不适用于所有数字。我确定我必须用 TypedArrays 做点什么,但我正在努力将所有东西放在一起。
也许这与这个问题类似: Chrome native messaging doesn't accept messages of certain sizes (Windows)
Windows-only: Make sure that the program's I/O mode is set to O_BINARY. By default, the I/O mode is O_TEXT, which corrupts the message format as line breaks (\n = 0A) are replaced with Windows-style line endings (\r\n = 0D 0A). The I/O mode can be set using __setmode.
这里的问题是,Firefox 默认尝试将标准输出读取为 UTF-8 流。由于 UTF-8 不使用完整的第一个字节,因此您会得到损坏的字符,例如 255。解决方案是告诉 Firefox 以二进制编码读取,这意味着您稍后必须手动解析实际的消息内容。
var childProcess = spawn("mybin", [ '-a' ], { encoding: null });
你的监听器会像
一样工作var decoder = new TextDecoder("utf-8");
var readIncoming = (data) => {
// read the first four bytes, which indicate the size of the following message
var size = (new Uint32Array(data.subarray(0, 4).buffer))[0];
//TODO: handle size > data.byteLength - 4
// read the message
var message = decoder.decode(data.subarray(4, size));
//TODO: do stuff with message
// Read the next message if there are more bytes.
if(data.byteLength > 4 + size)
readIncoming(data.subarray(4 + size));
};
childProcess.stdout.on('data', (data) => {
// convert the data string to a byte array
// The bytes got converted by char code, see https://dxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/sdk/system/child_process/subprocess.js#357
var bytes = Uint8Array.from(data, (c) => c.charCodeAt(0));
readIncoming(bytes);
});