Rust 元宇宙 10 —— 接入和协议
做完了所有的准备工作之后,我们需要迈出重要的一步,创建一个真实的玩家,通过客户端进入元宇宙,并看到视野内的一切,包括自己和其他角色(玩家或者宠物/NPC)。
客户端采用什么语言开发是无所谓的,我们只要规定客户端接入元宇宙所使用的的协议和数据格式就行了,比如说 C/C++,rust,Java,JS 都可以,使用 Unity ,Unreal,或者 Cocos 引擎也无所谓。
我们首选需要选择的,是客户端和元宇宙服务器之间使用的通讯协议,大概有下面几种选择:
UDP
建立在 UDP 上的可靠传输协议(UDX UDT 等)
QUIC(WebRTC 使用的协议)
TCP
websocket
http/https
其中 UDP 是最基础的,不可靠传输协议,游戏内部的语音可以考虑使用这个协议
UDX 和 UDT 等非标准的 可靠 UDP 传输协议基本上都是自己实现了 TCP 的重传算法,以期望在 5G 时代有更好的表现,考虑到元宇宙的开放性和普适性,我们暂时不考虑。
QUIC 是 google 实现的 WebRTC 的底层协议,也是一种 自己实现的可靠 UDP 协议,是下一代 http2 协议的基础,可以作为我们的备选。
TCP 是最传统,最古老的 C/S 协议了,大部分客户端游戏都是采用这个协议的,当然也可以作为我们的备选,最大的问题是,网页的开发语言 Javascrit 没有办法直接支持这个协议。
websocket 是来源于网页,但是客户端也可以使用的协议,建立在 TCP 之上,但是增加了一些加密握手等特性,其弱点就是接入的开销会增加(TLS 握手会消耗 CPU 和内存)。
http/https 是最广泛使用的网站协议,大量的页游,手游都使用了这个协议,这个协议最大的问题就是不支持长链接,客户端很难获得服务器的通知,而且基于文本的 http 协议本身的开销巨大。
综上所述,如果不考虑网页接入,可以选择的有 QUIC WebSocket 和 TCP。
如果考虑支持网页接入,可供选择的只剩下 Websocket 了。
Rust 对 Websocket 的支持还是比较完善的,Actix-web 和 Axum 都对 Websocket 提供了支持
下面是 Axum 提供 Websocket 服务的代码
解决了底层传输协议问题之后,我们又面临一个选择,我们怎么规定 客户端和云宇宙服务器之间的消息格式?
这里又有两种基本的方法:
基于 Schema 和不基于 Schema 的方法
基于 Schema 的方法,就是 使用 IDL 来独立描述接口,并生成 接口的代码,比如说
google 的 Protocolbuffer。一个典型的消息定义如下
Apache 的 thrift
等等
优点是能够生成高性能的接口代码,缺点是不够灵活,任何接口的调整都需要重新编译代码
不基于 Schema 的方法,就是规定消息的二进制规范,但是不跟接口挂钩起来,应用层自己根据翻译出来的消息内容,决定如何处理。
比如说 使用 MessagePack 对消息进行序列化处理。
这两种方案各有优劣,对于大型项目来说,基于 Schema 的方案更加严谨和方便协调,对于小型个人项目来说,不基于 Schema 更灵活,实现更快。
综上所述,我们的元宇宙采用 不基于 Schema 的 messagepack 方案。
我们在 share::msg 里面定义 WorldRequest 如下
使用 messagepack 我们可以方便的序列化,代码如下
序列化的结果输出如下
评论