Https 有没有办法在与hyper相同的端口上运行Tungstenite?
我正在尝试为一个简单的浏览器游戏制作一个Rust的web服务器。我希望服务器能够通过HTTPS交付页面,但也能够通过WebSocket进行通信。我计划将此服务器放在Heroku上,但由于每个应用程序只允许一个端口,因此我必须使WebSocket服务器在与其他HTTPS代码相同的端口上运行 看起来是这样,但那个板条箱使用了过时版本的Https 有没有办法在与hyper相同的端口上运行Tungstenite?,https,rust,Https,Rust,我正在尝试为一个简单的浏览器游戏制作一个Rust的web服务器。我希望服务器能够通过HTTPS交付页面,但也能够通过WebSocket进行通信。我计划将此服务器放在Heroku上,但由于每个应用程序只允许一个端口,因此我必须使WebSocket服务器在与其他HTTPS代码相同的端口上运行 看起来是这样,但那个板条箱使用了过时版本的hyper,似乎不再维护。板条箱tokio_tungstenite要更新得多 问题在于hyper和tungstenite都有自己的HTTP协议实现,WebSocket通
hyper
,似乎不再维护。板条箱tokio_tungstenite
要更新得多
问题在于
hyper
和tungstenite
都有自己的HTTP协议实现,WebSocket通过HTTP协议运行,无法在两者之间转换。这意味着,一旦HTTPS请求被hyper
或tungstenite
解析,就无法继续由另一部分进行处理,因此您不能真正尝试连接WebSocket并匹配tungstenite
中的错误,然后通过hyper
进行处理,您也不能通过hyper
解析请求,并检查它是否是WebSocket请求并将其发送到tungstenite
。有什么办法可以解决这个问题吗?我认为应该可以做到这一点,tungstenite
和tokio tungstenite
允许您指定自定义标题(有帮助函数,前缀为hdr
),因此根据您使用的hyper
版本,如果您可以将请求转换为某种形式,当可以提取标题时,您可以将其传递给tungstenite
您可能还想尝试使用
warp
板条箱,它构建在hyper
之上,并在引擎盖下使用tungstenite
作为websocket支持,因此如果您想编写自己版本的warp
,可以查看源代码(源代码可能包含如何将hyper
和tungstenite
结合使用的提示)。您可以这样做,但它非常灵活。您必须使用tokio tungstenite
,自己握手(检查标题,设置响应标题)并在运行时生成一个新的未来,该未来将处理websockets连接在具有最新版本的hyper的请求正文上,然后可以将连接传递到tokio_tungstenite::WebSocketStream::from_raw_socket以将其转换为WebSocket连接
示例处理程序(请注意,这不会完全检查请求头,并假设我们需要升级):
fn websocket(请求)->结果
fn websocket(req: Request<Body>) -> Result<Response<Body>, &'static str> {
// TODO check other header
let key = match req.headers().typed_get::<headers::SecWebsocketKey>() {
Some(key) => key,
None => return Err("failed to read ws key from headers"),
};
let websocket_future = req
.into_body()
.on_upgrade()
.map_err(|err| eprintln!("Error on upgrade: {}", err))
.and_then(|upgraded| {
let ws_stream = tokio_tungstenite::WebSocketStream::from_raw_socket(
upgraded,
tokio_tungstenite::tungstenite::protocol::Role::Server,
None,
);
let (sink, stream) = ws_stream.split();
sink.send_all(stream)
.map(|_| ())
.map_err(|err| error!("{}", err))
});
hyper::rt::spawn(websocket_future);
let mut upgrade_rsp = Response::builder()
.status(StatusCode::SWITCHING_PROTOCOLS)
.body(Body::empty())
.unwrap();
upgrade_rsp
.headers_mut()
.typed_insert(headers::Upgrade::websocket());
upgrade_rsp
.headers_mut()
.typed_insert(headers::Connection::upgrade());
upgrade_rsp
.headers_mut()
.typed_insert(headers::SecWebsocketAccept::from(key));
Ok(upgrade_rsp)
}