用ws-rs的时候,看demo:
connect(HUOBI, |out| {
out.send(r#"{"event":"addChannel","channel":"ltcbtc_depth"}"#);
move |msg| {
println!("Client got message '{}'. ", msg);
out.close(CloseCode::Normal)
}
});
后面返回个 closure,开始以为是啥奇怪的语法呢,msg就拿到了服务端发送的东西,好神奇!
看connect代码:
pub fn connect<U, F, H>(url: U, factory: F) -> Result<()>
where
U: Borrow<str>,
F: FnMut(Sender) -> H,
H: Handler,
{
let mut ws = WebSocket::new(factory)?;
let parsed = url::Url::parse(url.borrow()).map_err(|err| {
Error::new(
ErrorKind::Internal,
format!("Unable to parse {} as url due to {:?}", url.borrow(), err),
)
})?;
ws.connect(parsed)?;
ws.run()?;
Ok(())
}
我们输入的应该是个 factory,然后通过factory创建了ws。
我们再看看factory定义
/// A trait for creating new WebSocket handlers.
pub trait Factory {
type Handler: Handler;
fn connection_made(&mut self, _: Sender) -> Self::Handler;
#[inline]
fn on_shutdown(&mut self) {
debug!("Factory received WebSocket shutdown request.");
}
#[inline]
fn client_connected(&mut self, ws: Sender) -> Self::Handler {
self.connection_made(ws)
}
#[inline]
fn server_connected(&mut self, ws: Sender) -> Self::Handler {
self.connection_made(ws)
}
#[inline]
fn connection_lost(&mut self, _: Self::Handler) {}
}
但是我们输入的是个closure啊???
再看看我们输入函数在where的限定
F: FnMut(Sender) -> H
H: Handler
输入是个Sender,返回是个Handler,所以我们demo里面的out是个Sender,返回的
move |msg| {
println!("Client got message '{}'. ", msg);
out.close(CloseCode::Normal)
}
是个Handler.
继续疑问:我输入是个函数呀,怎么就符合Factory这个呢
看看Factory trait里面
impl<F, H> Factory for F
where
H: Handler,
F: FnMut(Sender) -> H,
{
type Handler = H;
fn connection_made(&mut self, out: Sender) -> H {
self(out)
}
}
他给 FnMut(Sender) -> H实现了Factory trait,connection_made也是Factory trait里面唯一没有默认实现的,所以当connection创建之后,就调用我们的这个函数,把out给他,并返回一个Handler。
OK到这儿就只有一个问题了,我们返回的是个closuzre啊,同理。。。也是给这个closuzre实现了Handler trait,看看代码
impl<F> Handler for F
where
F: Fn(Message) -> Result<()>,
{
fn on_message(&mut self, msg: Message) -> Result<()> {
self(msg)
}
}
同上,on_message也是Handler唯一没有默认实现的了,所以这里这个等于
move |msg| {
println!("Client got message '{}'. ", msg);
out.close(CloseCode::Normal)
}
Top comments (0)