如何在Firefox插件中向子进程发送消息,如Chrome原生消息
How to message child process in Firefox add-on like Chrome native messaging
我正在尝试使用Firefox的附加SDK来模拟Chrome的本地消息传递功能。具体来说,我使用child_process模块和emit方法来与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做些什么,但我很难把所有东西都放在一起。
这里的问题是,Firefox在默认情况下试图将stdout读取为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原生消息;t接受特定大小的消息(Windows)
仅限Windows:确保程序的I/O模式设置为O_BINARY。默认情况下,I/O模式为O_TEXT,这会破坏消息格式,因为换行符(=0A)被替换为Windows样式的换行符(''r''n=0D 0A)。可以使用__setmode设置I/O模式。
相关文章:
- Ajax聊天消息重复而不仅仅是更新
- 如果localstorage为空,则显示欢迎消息
- 绑定时将Parsley minlength消息作为选项传递时,未对其进行自定义
- 离开页面时弹出消息
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- 消息显示之外的淘汰验证
- 选项卡侦听器未被来自后台脚本的消息激活
- jQuery在输入下验证post错误消息
- Scipt未在选定选项卡中执行以发送和接收消息
- js代码从jQuery转换为原生代码
- 检查xmlhttprequest问题的消息
- AngularJs对ng消息的自定义替换
- ng消息仅在触摸时显示错误,并在错误的初始显示上转换
- 当用户按下回车键时,自动在text区域/text中插入消息
- 如果消息框答案为YES,则用Javascript填写表单
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- 解析云代码错误:解析.错误{代码:141,消息:“未调用成功/错误”}
- 如何在Firefox插件中向子进程发送消息,如Chrome原生消息
- 谷歌打包应用原生消息传递
- 在Chrome原生消息传递:有多长是本地应用实例对象的生命周期