我正在尝试使用 Mio 和反应器模式来实现服务器。我希望我Reactor
同时处理TcpListeners
和TcpStreams
,所以在这里抽象是我真正的挑战。
我有一个特性ReAgent
,它实现了各种处理程序来通知Reactor
状态的变化,同时Reactor
通知每个人ReAgent
关于那个重要的事件ReAgent
。反过来,我将有两种不同的ReAgent
类型,一种用于接受 ( TcpListeners
),它会生成客户端 ( TcpStreams
) 以传递回Reactor
事件处理。Reactor
用于多个服务器端点的非常标准的模式;在我的职业生涯中,我已经用 C/C++ 编写了六个这样的代码。删除有关 myTokenPool
等的详细信息,这就是我头疼的地方:
pub struct Reactor<'a> {
poll: Poll,
agents: HashMap<Token, Box<ReAgent + 'a>>,
tokens: TokenPool,
}
impl<'a> Reactor<'a> {
pub fn add_agent<R: ReAgent + 'a>(&mut self, mut agent: Box<R>) -> Result<()>
{
if let Some(next_token) = self.tokens.pop() {
agent.set_token(next_token);
self.agents.insert(agent.get_token(), agent);
return Ok(())
}
bail!(ErrorKind::ConnectionsExhausted)
}
}
//...
/// Received a Box<ReAgent> (a Client);
/// add and start conversation
Some(boxed_agent) => self.add_agent(boxed_agent)
当我编译这个时,我得到:
Some(boxed_agent) => self.add_agent(boxed_agent)
^^^^^^^^^ `reagent::ReAgent` does not have a constant size known at compile-time
...我根本不明白。这是一个Box
。ABox
在编译时具有已知的常量大小。这就是使用Box
支持动态类型对象的全部意义,对吧?客户端具有已知大小,它是ReAgent
.
我错过了什么?
我知道我可能需要RefCell
稍后再使用,因为我正在改变ReAgent
以设置其轮询令牌;那是以后的事,我只是想过去。