1

我正在弄清楚如何使用tokio-proto板条箱,特别是在建立连接时进行的握手。我从官方文档中得到了这个例子:

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实现应该如何查看该密钥?它应该存储在哪里?

4

1 回答 1

1

您可以将字段添加到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()用于存储东西。然后,当您Arc::Mutex::HashMapmain()函数中创建 时,您也可以访问方法中的整个内容serve(),这意味着您可以将其传递给 Service 对象实例化,然后握手将在call().

于 2017-06-20T06:55:58.453 回答