我正在尝试使用Mio和reactor模式实现服务器。我希望我的Reactor
同时处理TcpListeners
和TcpStreams
,因此在这里抽象是我真正的挑战。
我有一个特征ReAgent
,它实现了各种处理程序,用于通知Reactor
状态的变化,同时Reactor
会通知每个人ReAgent
重要的事件ReAgent
1}}。反过来,我会有两种不同的ReAgent
类型,一种用于接受(TcpListeners
),它会产生客户端(TcpStreams
)以传回Reactor
事件处理。多个服务器端点的非常标准的Reactor
模式;在我的职业生涯中,我用C / C ++编写了其中的六个。关于我TokenPool
等的详细信息,这里有我头疼的地方:
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
。 Box
在编译时具有已知的常量大小。这就是使用Box
来支持动态类型对象的重点,对吧?客户端具有已知的大小,它是ReAgent
的具体实现。
我错过了什么?
我知道我以后可能不得不使用RefCell
,因为我正在改变ReAgent
来设置其轮询令牌;对于以后的事情,我只想过去。