如何从 tokio-proto 连接握手中检索信息?
How to retrieve information from the tokio-proto connection handshake?
我正在弄清楚如何使用 tokio-proto
crate,特别是在建立连接时进行的握手。我从 official documentation 工作中得到了示例:
impl<T: AsyncRead + AsyncWrite + 'static> ClientProto<T> for ClientLineProto {
type Request = String;
type Response = String;
/// `Framed<T, LineCodec>` is the return value of `io.framed(LineCodec)`
type Transport = Framed<T, line::LineCodec>;
type BindTransport = Box<Future<Item = Self::Transport, Error = io::Error>>;
fn bind_transport(&self, io: T) -> Self::BindTransport {
// Construct the line-based transport
let transport = io.framed(line::LineCodec);
// Send the handshake frame to the server.
let handshake = transport.send("You ready?".to_string())
// Wait for a response from the server, if the transport errors out,
// we don't care about the transport handle anymore, just the error
.and_then(|transport| transport.into_future().map_err(|(e, _)| e))
.and_then(|(line, transport)| {
// The server sent back a line, check to see if it is the
// expected handshake line.
match line {
Some(ref msg) if msg == "Bring it!" => {
println!("CLIENT: received server handshake");
Ok(transport)
}
Some(ref msg) if msg == "No! Go away!" => {
// At this point, the server is at capacity. There are a
// few things that we could do. Set a backoff timer and
// try again in a bit. Or we could try a different
// remote server. However, we're just going to error out
// the connection.
println!("CLIENT: server is at capacity");
let err = io::Error::new(io::ErrorKind::Other, "server at capacity");
Err(err)
}
_ => {
println!("CLIENT: server handshake INVALID");
let err = io::Error::new(io::ErrorKind::Other, "invalid handshake");
Err(err)
}
}
});
Box::new(handshake)
}
}
但是官方文档只提到了握手,没有状态信息。有没有一种通用的方法可以从握手中检索和存储有用的数据?
例如,如果在握手期间(在建立连接后的第一条消息中)服务器发送了一些客户端稍后应该使用的密钥,ClientProto
实现应该如何查看该密钥?它应该存储在哪里?
您可以向 ClientLineProto
添加字段,所以这应该有效:
pub struct ClientLineProto {
handshakes: Arc<Mutex<HashMap<String, String>>>
}
然后您可以引用它并根据需要存储数据:
let mut handshakes = self.handshakes.lock();
handshakes.insert(handshake_key, "Blah blah handshake data")
这种访问方式可以在 bind_transport()
中用于存储内容。然后,当您在 main()
函数中创建 Arc::Mutex::HashMap
时,您也可以访问 serve()
方法中的所有内容,这意味着您可以将其传递给服务对象实例化然后握手将在 call()
.
期间可用
我正在弄清楚如何使用 tokio-proto
crate,特别是在建立连接时进行的握手。我从 official documentation 工作中得到了示例:
impl<T: AsyncRead + AsyncWrite + 'static> ClientProto<T> for ClientLineProto {
type Request = String;
type Response = String;
/// `Framed<T, LineCodec>` is the return value of `io.framed(LineCodec)`
type Transport = Framed<T, line::LineCodec>;
type BindTransport = Box<Future<Item = Self::Transport, Error = io::Error>>;
fn bind_transport(&self, io: T) -> Self::BindTransport {
// Construct the line-based transport
let transport = io.framed(line::LineCodec);
// Send the handshake frame to the server.
let handshake = transport.send("You ready?".to_string())
// Wait for a response from the server, if the transport errors out,
// we don't care about the transport handle anymore, just the error
.and_then(|transport| transport.into_future().map_err(|(e, _)| e))
.and_then(|(line, transport)| {
// The server sent back a line, check to see if it is the
// expected handshake line.
match line {
Some(ref msg) if msg == "Bring it!" => {
println!("CLIENT: received server handshake");
Ok(transport)
}
Some(ref msg) if msg == "No! Go away!" => {
// At this point, the server is at capacity. There are a
// few things that we could do. Set a backoff timer and
// try again in a bit. Or we could try a different
// remote server. However, we're just going to error out
// the connection.
println!("CLIENT: server is at capacity");
let err = io::Error::new(io::ErrorKind::Other, "server at capacity");
Err(err)
}
_ => {
println!("CLIENT: server handshake INVALID");
let err = io::Error::new(io::ErrorKind::Other, "invalid handshake");
Err(err)
}
}
});
Box::new(handshake)
}
}
但是官方文档只提到了握手,没有状态信息。有没有一种通用的方法可以从握手中检索和存储有用的数据?
例如,如果在握手期间(在建立连接后的第一条消息中)服务器发送了一些客户端稍后应该使用的密钥,ClientProto
实现应该如何查看该密钥?它应该存储在哪里?
您可以向 ClientLineProto
添加字段,所以这应该有效:
pub struct ClientLineProto {
handshakes: Arc<Mutex<HashMap<String, String>>>
}
然后您可以引用它并根据需要存储数据:
let mut handshakes = self.handshakes.lock();
handshakes.insert(handshake_key, "Blah blah handshake data")
这种访问方式可以在 bind_transport()
中用于存储内容。然后,当您在 main()
函数中创建 Arc::Mutex::HashMap
时,您也可以访问 serve()
方法中的所有内容,这意味着您可以将其传递给服务对象实例化然后握手将在 call()
.