【发布时间】:2020-08-10 01:46:13
【问题描述】:
我在为 rust 中的 unix 套接字服务器创建守护程序时遇到了困难。在像 node.js 这样的语言中,我只会产生一个分离的进程。但生锈似乎更具挑战性。
(所有工作都在 unix 环境中)
这是一个简单的例子。我写了:
use std::os::unix::net::{UnixListener, UnixStream};
use std::path::{Path};
use std::io::{Read, Write};
use std::{fs};
use std::thread;
fn handle_stream(mut stream: UnixStream) {
loop {
let mut read = [0; 1028];
match stream.read(&mut read) {
Ok(n) => {
if n == 0 {
// connection was closed
println!("connection closed?");
break;
}
let msg = String::from_utf8(read.to_vec()).unwrap();
println!("SERVER: {} received from remote client.", msg);
match stream.write_all(&read[0..n]) {
Ok(_) => {}
Err(e) => println!("Error writing to socket: {}", e),
}
}
Err(err) => {
panic!(err);
}
}
}
println!("SERVER: Ending connection with client.");
}
fn server_start() {
// remove existing sock if exists
let _did_remove = fs::remove_file("/Users/tom/desktop/app.sock");
// socket location
let socket_file = "/Users/tom/desktop/app.sock";
let socket = Path::new(socket_file);
// Bind to socket
let listener = match UnixListener::bind(&socket) {
Err(_) => panic!("failed to bind socket"),
Ok(stream) => stream,
};
println!("Server started, waiting for clients");
for conn in listener.incoming() {
match conn {
Ok(stream) => {
// spawn a new thread for each incoming
thread::spawn(|| handle_stream(stream));
}
Err(err) => {
println!("Error connecting to client: {}", err);
break;
}
}
}
}
fn main() {
server_start();
}
【问题讨论】:
-
我希望,我实际上已经读过这篇文章太多次了。我猜 rust 在该帖子得到答复后从 Command 中删除了分离的方法。
-
你确定你需要一个真正的守护进程而不是一个简单的 systemd 服务(假设你在 Linux 上)?后者更容易,并且在大多数情况下都可以正常工作。例如,请参阅medium.com/@benmorel/…
-
这看起来像要走的路,我稍后会发布一个示例
-
我赞同@kreo 不打扰的建议。 Systemd 文档discourages self-daemonization:“对于开发新型守护进程,不需要执行为 SysV 守护进程推荐的初始化步骤。像 systemd 这样的新型初始化系统使它们都变得多余。此外,由于其中一些步骤干扰init系统的进程监控、文件描述符传递等功能,作为新式服务运行时建议不要执行。"