I want to implement a node addon with napi-rs for sending and receiving msg by TCP;
here is my code
use napi::{bindgen_prelude::Result, Error, Status};
use std::sync::{Arc, Mutex};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
// store TcpStream
lazy_static::lazy_static! {
static ref TCP_STREAM: Arc<Mutex<Option<TcpStream>>> = Arc::new(Mutex::new(None));
}
#[napi]
pub async fn send_msg() -> Result<()> {
let mut tcp = TCP_STREAM.lock().unwrap();
let tcp_stream = tcp
.as_mut()
.ok_or_else(|| Error::new(Status::GenericFailure, "Not connected".to_string()))?;
// here send msg to server
tcp_stream.write("hello Rust".as_bytes()).await?;
Ok(())
}
#[napi]
pub async fn listen_to_server() -> Result<u32> {
let addr = "127.0.0.1:8899";
let stream = TcpStream::connect(addr).await.unwrap();
let p = TCP_STREAM.clone();
let mut tcp = p.lock().unwrap();
*tcp = Some(stream);
let p2 = TCP_STREAM.clone();
tokio::spawn(async move {
loop {
let mut mut_tcp = p2.lock().unwrap();
let tcp_in = mut_tcp.as_mut().unwrap();
let mut str = String::new();
tcp_in.read_to_string(&mut str).await;
// here listen server msg and do something
}
});
Ok(1)
}
then I get an error at " tokio::spawn"
future cannot be sent between threads safely
within `{async block@src/lib.rs:39:16: 46:4}`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, Option<tokio::net::TcpStream>>
how to dispatch a task if handle_message is async fn and there is a loop in handle_message. the task is to start a TcpStream and to listen to data by try_read in a loop.
I want to new a TcpStream client. the duty of the client is to send msg to the server and to receive msg from the server. for APIs exported to Nodejs. I want a this
import {createClient, sendMsg} from './node-addon-build-by-rusr-napi-rs'
async function main () {
await createClient('address', { onData: (msg) => {
console.log("msg from the server is", msg)
// handle msg
// maybe
sendMsg({type: 'login', data: encrypt(data)})
} })
}
On Rust side, in napi-rs doc, I find async and tokio.
at first, sharing TcpStream across multiple async fns annotated by #[napi] occurred to me.
Then you mentioned actor, and I just took a look at it, but I feel that due to the spread of await, it will still block somewhere anyway.