I want to implement tcp client using mio. This is my code:
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>,
},
}
}
}
and code of my auth handler:
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
}
}
on compile I got an error "error[E0621]: explicit lifetime required in the type of connection":
self.connection = Some(&connection);
^^^^^^^^^^^^^^^^^ lifetime `'static` required
how to fix it ? From my side I am not sure if static lifetime is OK since I want to destroy connection once authenticated and logged in.
The lifetime of
connectionis really'a, but from the code you've posted nobody owns theTcpStream. You could fix the specific error you're having by using theAuthHandlers lifetime:But I would expect that you would then get other errors, because in effect
Clientis a self-referential struct.So one way to share the connection between these objects would be to put it inside a
Arc<Mutex<TcpStream>>and share that between your two objects:then the
TcpStreamwill stay alive as long as you need it. Of course, you would need to.lock()it whenever you use it.Another option would be to only pass the
TcpStreamtoAuthHandlerwhen it uses it: