2 releases

0.1.1 Dec 13, 2024
0.1.0 Sep 26, 2024

#917 in Network programming

Download history 124/week @ 2024-09-25 13/week @ 2024-10-02 5/week @ 2024-10-09 3/week @ 2024-10-16 1/week @ 2024-11-06 6/week @ 2024-12-04 137/week @ 2024-12-11 6/week @ 2024-12-18

149 downloads per month

MIT/Apache

110KB
2.5K SLoC

hcnet

虚拟化服务端及客户端的底层,可以轻松的切换tcp/tcps/ws/wss/udp等协议, 以方便在任意情况下切换协议。后续例如在线数,流控等需求再来进行处理。

回调处理

统一用回调进行处理函数


/// 连接处理回调函数
#[async_trait]
pub trait Handler {
    /// 此接口只有在服务端接受服务时进行触发
    /// 接收新的端口连接, 如果处理将在此触发
    async fn on_accept(&mut self, conn: NetConn) -> NetResult<()> {
        let _conn = conn;
        unreachable!("Listener must impl accept")
    }

    /// 此接口在可以发送消息时触发
    /// 例如websocket将在握手成功后触发该函数
    async fn on_open(&mut self) -> NetResult<()> {
        trace!("ws on_open");
        Ok(())
    }

    /// 此接口在远程服务端被关闭时进行触发
    async fn on_close(&mut self, code: CloseCode, reason: String) {
        trace!(
            "on_close code = {}, reason = {reason}",
            Into::<u16>::into(code)
        );
    }

    /// ping消息收到, 将会自动返回pong消息
    async fn on_ping(&mut self, data: Vec<u8>) -> NetResult<Vec<u8>> {
        trace!("on_ping");
        Ok(data)
    }

    /// pong消息
    async fn on_pong(&mut self, data: Vec<u8>) -> NetResult<()> {
        let _data = data;
        trace!("on_pong");
        Ok(())
    }

    /// message信息收到
    async fn on_message(&mut self, msg: Message) -> NetResult<()> {
        let _ = msg;
        Ok(())
    }

    async fn on_request(&mut self, req: Request<Vec<u8>>) -> NetResult<Response<Vec<u8>>> {
        WsHandshake::build_request(&req)
    }

    async fn on_response(&mut self, res: Request<Vec<u8>>) -> NetResult<()> {
        let _ = res;
        Ok(())
    }
}


服务端监听

tcp监听

NetConn::tcp_bind("0.0.0.0:2003", Settings::default()).await

ws监听

NetConn::ws_bind("0.0.0.0:2003", Settings::default()).await

wss监听

监听时将证书信息配置即可轻松的支持wss协议

let mut settings = Settings {
    domain: Some("test.wmproxy.net".to_string()),
    cert: Some("key/example.com.pem".to_string()),
    key: Some("key/example.com.key".to_string()),
    ..Settings::default()
};
NetConn::ws_bind("0.0.0.0:2003", settings).await

kcp(udp)监听

NetConn::kcp_bind("0.0.0.0:2003").await

基本上监听和一般的socket监听一致,复杂程度类似,即可任意切换任何协议。

服务端启动监听

let h = conn.run_handler(|_| ServerHandler).await.unwrap();
let _ = tokio::join!(h);

具体示例可参考server_echo

客户端连接

tcp连接

NetConn::tcp_connect("127.0.0.1:2003").await

ws连接

NetConn::ws_connect("ws://example.com:2003").await

wss连接

NetConn::ws_connect("wss://example.com:2003").await

kcp(udp)连接

NetConn::kcp_connect("wss://example.com:2003").await

客户端启动监听

let (mut sender, receiver) = NetSender::new(10, 1);
let _ = conn.run_with_handler(
        ClientHandler {
            sender: sender.clone(),
        },
        receiver,
    ).await;

或者

let _ = conn.run_handler(|sender| ClientHandler { sender }).await;

具体示例可参考client_echo

启动demo

先启动服务端

cargo run --example server_echo tcp

再启动客户端

cargo run --example client_echo tcp

Dependencies

~16–26MB
~466K SLoC