Rust + mio tcp 客户端:连接类型需要明确的生命周期
Rust + mio tcp client: explicit lifetime required in the type of connection
我想用mio实现tcp客户端。这是我的代码:
pub struct Client<'a> {
pub connected: bool,
connection: Option<&'a TcpStream>,
auth_handler: auth::AuthHandler<'a>,
}
impl Client<'_> {
pub fn connect(&mut self, host: &str, port: i16) {
let addr_list = format!("{}:{}", host, port)
.to_socket_addrs()
.unwrap();
let addr = addr_list.last().unwrap();
match TcpStream::connect(addr) {
Ok(stream) => {
self.connected = true;
self.connection = Some(&stream);
self.auth_handler.init(self.connection.unwrap());
self.auth_handler.authenticate("login".to_string(), "password".to_string());
println!("Connected to {}:{}", host, port);
}
Err(..) => {
println!("Cannot connect !");
}
}
}
pub fn listen(&mut self) {
let mut connection = self.connection.as_mut().unwrap();
let mut poll = Poll::new().unwrap();
let mut events = Events::with_capacity(256);
poll.registry().register(
connection,
CLIENT,
Interest::READABLE | Interest::WRITABLE
);
loop {
poll.poll(&mut events, None).unwrap();
for event in events.iter() {
match event.token() {
CLIENT => {
if event.is_writable() {
// ...
}
if event.is_readable() {
println!("Data")
}
},
_ => (),
}
}
}
}
pub fn new<'a>() -> Client<'a> {
Client {
connected: false,
connection: None,
auth_handler: auth::AuthHandler {
connection: None::<&'a TcpStream>,
},
}
}
}
以及我的授权处理程序代码:
pub struct AuthHandler<'a> {
pub connection: Option<&'a TcpStream>,
}
impl AuthHandler {
pub fn authenticate(&self, login: String, password: String) {
// ...
}
pub fn new<'a>() -> AuthHandler<'a> {
AuthHandler {
connection: None::<&'a TcpStream>,
}
}
pub fn init(&mut self, connection: &TcpStream) {
self.connection = Some(&connection); // error here see ERRORS below
}
}
编译时出现错误“错误[E0621]:连接类型需要明确的生命周期”:
self.connection = Some(&connection);
^^^^^^^^^^^^^^^^^ lifetime `'static` required
如何解决?在我这边,我不确定 static
生命周期是否正常,因为我想在通过身份验证并登录后破坏连接。
connection
的生命周期实际上是 'a
,但从您发布的代码来看,没有人拥有 TcpStream
。您可以使用 AuthHandler
s 生命周期修复您遇到的特定错误:
impl<'a> AuthHandler<'a> {
pub fn authenticate(&self, login: String, password: String) {
// ...
}
pub fn new() -> AuthHandler {
AuthHandler {
connection: None,
}
}
pub fn init(&mut self, connection: &'a TcpStream) {
self.connection = Some(connection);
}
}
但我希望您随后会收到其他错误,因为实际上 Client
是一个 self-referential 结构。
因此,共享这些对象之间连接的一种方法是将其放入 Arc<Mutex<TcpStream>>
并在您的两个对象之间共享:
pub struct Client<'a> {
pub connected: bool,
connection: Option<Arc<Mutex<TcpStream>>>,
auth_handler: auth::AuthHandler<'a>,
}
pub struct AuthHandler {
pub connection: Option<Arc<Mutex<TcpStream>>>,
}
那么 TcpStream
只要你需要它就会一直存在。当然,您需要在每次使用时 .lock()
它。
另一种选择是仅在使用 TcpStream
时将其传递给 AuthHandler
:
pub struct AuthHandler;
impl AuthHandler {
pub fn authenticate(&self, login: String, password: String, stream: &TcpStream) {
// ...
}
}
我想用mio实现tcp客户端。这是我的代码:
pub struct Client<'a> {
pub connected: bool,
connection: Option<&'a TcpStream>,
auth_handler: auth::AuthHandler<'a>,
}
impl Client<'_> {
pub fn connect(&mut self, host: &str, port: i16) {
let addr_list = format!("{}:{}", host, port)
.to_socket_addrs()
.unwrap();
let addr = addr_list.last().unwrap();
match TcpStream::connect(addr) {
Ok(stream) => {
self.connected = true;
self.connection = Some(&stream);
self.auth_handler.init(self.connection.unwrap());
self.auth_handler.authenticate("login".to_string(), "password".to_string());
println!("Connected to {}:{}", host, port);
}
Err(..) => {
println!("Cannot connect !");
}
}
}
pub fn listen(&mut self) {
let mut connection = self.connection.as_mut().unwrap();
let mut poll = Poll::new().unwrap();
let mut events = Events::with_capacity(256);
poll.registry().register(
connection,
CLIENT,
Interest::READABLE | Interest::WRITABLE
);
loop {
poll.poll(&mut events, None).unwrap();
for event in events.iter() {
match event.token() {
CLIENT => {
if event.is_writable() {
// ...
}
if event.is_readable() {
println!("Data")
}
},
_ => (),
}
}
}
}
pub fn new<'a>() -> Client<'a> {
Client {
connected: false,
connection: None,
auth_handler: auth::AuthHandler {
connection: None::<&'a TcpStream>,
},
}
}
}
以及我的授权处理程序代码:
pub struct AuthHandler<'a> {
pub connection: Option<&'a TcpStream>,
}
impl AuthHandler {
pub fn authenticate(&self, login: String, password: String) {
// ...
}
pub fn new<'a>() -> AuthHandler<'a> {
AuthHandler {
connection: None::<&'a TcpStream>,
}
}
pub fn init(&mut self, connection: &TcpStream) {
self.connection = Some(&connection); // error here see ERRORS below
}
}
编译时出现错误“错误[E0621]:连接类型需要明确的生命周期”:
self.connection = Some(&connection);
^^^^^^^^^^^^^^^^^ lifetime `'static` required
如何解决?在我这边,我不确定 static
生命周期是否正常,因为我想在通过身份验证并登录后破坏连接。
connection
的生命周期实际上是 'a
,但从您发布的代码来看,没有人拥有 TcpStream
。您可以使用 AuthHandler
s 生命周期修复您遇到的特定错误:
impl<'a> AuthHandler<'a> {
pub fn authenticate(&self, login: String, password: String) {
// ...
}
pub fn new() -> AuthHandler {
AuthHandler {
connection: None,
}
}
pub fn init(&mut self, connection: &'a TcpStream) {
self.connection = Some(connection);
}
}
但我希望您随后会收到其他错误,因为实际上 Client
是一个 self-referential 结构。
因此,共享这些对象之间连接的一种方法是将其放入 Arc<Mutex<TcpStream>>
并在您的两个对象之间共享:
pub struct Client<'a> {
pub connected: bool,
connection: Option<Arc<Mutex<TcpStream>>>,
auth_handler: auth::AuthHandler<'a>,
}
pub struct AuthHandler {
pub connection: Option<Arc<Mutex<TcpStream>>>,
}
那么 TcpStream
只要你需要它就会一直存在。当然,您需要在每次使用时 .lock()
它。
另一种选择是仅在使用 TcpStream
时将其传递给 AuthHandler
:
pub struct AuthHandler;
impl AuthHandler {
pub fn authenticate(&self, login: String, password: String, stream: &TcpStream) {
// ...
}
}