Rust 不接受来自原生消息传递的 stdin 输入 - Firefox



我正在用 Web API 从 Firefox 制作一个原生消息传递应用程序。该扩展应该调用一个解析 stdin 的应用程序,然后根据它解析的一些数据调用我的另一个 rust 应用程序,但没有明显的原因,rust 应用程序不接受来自 Firefox 的输入(当我手动执行此操作时它可以工作(。 这是扩展的代码:

/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
console.log("Sending:  ping");
var sending = browser.runtime.sendNativeMessage(
"themefox_manager",
"ping");
sending.then(onResponse, onError);
});

function onResponse(response) {
console.log("Received " + response);
}

function onError(error) {
console.log(`Error: ${error}`);
}

这是 Rust 应用程序的代码:

use std::fs;
use std::io;
use std::io::prelude::*;
fn main() {
let stdin = io::stdin();
for line in stdin.lock().lines() {
let mut file = fs::File::create("/home/user/filename.txt").unwrap();
//
if line.unwrap() == "ping" {
file.write_all(b"TEST").expect("Error");
}
}
}

奇怪的是,当我关闭Firefox时,我家目录中的文本文件首先出现,而不是在应用程序启动时。而且它也没有文本测试。

感谢您的任何帮助!

干杯

我设法制作了自己的解决方案,从这个板条箱中取出一点。

快速说明:"如果要跳过所有代码并立即希望从模板存储库开始编码,请搜索到此解决方案的底部,您应该能够在那里找到更多信息。

读取输入然后返回的代码如下所示:

pub fn read_input<R: Read>(mut input: R) -> io::Result<serde_json::Value> {
let length = input.read_u32::<NativeEndian>().unwrap();
let mut buffer = vec![0; length as usize];
input.read_exact(&mut buffer)?;
let json_val: serde_json::Value = serde_json::from_slice(&buffer).unwrap();
Ok(json_val)
}

代码的作用是读取作为参数传递给函数的输入,然后读取它在 json var 中解析它并返回它的成功/错误值。

该代码在 main.rs 文件中使用,如下所示:

let json_val = match lib::read_input(io::stdin()) {
Err(why) => panic!("{}", why.to_string()),
Ok(json_val) => json_val,
};

在这里,输入作为参数传递给read_input函数。

为了发送代码,我使用了以下函数:

pub fn write_output<W: Write>(mut output: W, value: &serde_json::Value) -> io::Result<()> {
let msg = serde_json::to_string(value)?;
let len = msg.len();
// Chrome won't accept a message larger than 1MB
if len > 1024 * 1024 {
panic!("Message was too large", length: {}, len)
}
output.write_u32::<NativeEndian>(len as u32)?;
output.write_all(msg.as_bytes())?;
output.flush()?;
Ok(())
}

它获取标准输出和作为参数传递的消息。然后,该函数将消息写入输出(通常是 stdout,也可以是用于调试目的的文件(。

调用函数write_output的代码如下:


let response = serde_json::json!({ "msg": "pong" });
match lib::write_output(io::stdout(), &response) {
Err(why) => panic!("{}", why.to_string()),
Ok(_) => (),
};

项目使用这些依赖项,因此请确保将它们添加到Cargo.toml

"byteorder" = "*"
"serde_json" = "*"

main.rs 文件的导入包括:

mod lib;
use std::io;

对于两个函数所在的 lib.rs 文件:

extern crate serde_json;
use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
use std::error::Error;
use std::fs;
use std::io;
use std::io::{Read, Write};

我还创建了一个 git 模板存储库,以便您可以快速开始,您可以在此处找到它。

最新更新