Websocket 库和 JSON RPC 库选型
WebSocket 库选型
C/C++ 跨平台 WebSocket 库备选方案:
uWebSockets
uWebSockets,µWS ("microWS") 是一个客户端和服务器的 WebSocket 和 HTTP 实现。它简单、高效且轻量级。
这个库在底层依赖于 libuv 库,作为异步网络 I/O 库。
libwebsockets
规范 libwebsockets.org websocket 库
在 Mac OS 上通过如下方式编译这个库:
$ git clone https://github.com/warmcat/libwebsockets.git
$ cd libwebsockets
$ mkdir build
$ cd build
$ cmake ..
$ make
一些比较老版本的 Mac OS 在上面执行 cmake ..
会报出如下的错误:
-- Performing Test LWS_HAVE_VISIBILITY - Success
Compiling with SSL support
CMake Error at /usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_INCLUDE_DIR)
Call Stack (most recent call first):
/usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
/usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindOpenSSL.cmake:370 (find_package_handle_standard_args)
CMakeLists.txt:1438 (find_package)
-- Configuring incomplete, errors occurred!
See also "/Users/netease/Projects/CppWebsockets/libwebsockets/build/CMakeFiles/CMakeOutput.log".
See also "/Users/netease/Projects/CppWebsockets/libwebsockets/build/CMakeFiles/CMakeError.log".
这主要是系统默认的 OpenSSL 库版本过老导致的。这个问题可以通过安装一个新版本的 OpenSSL 库,并在执行 cmake ..
之前定义系统环境变量 OPENSSL_ROOT_DIR
来解决,如 OpenSSL 安装在 /usr/local/opt/openssl/
目录中,则像下面这样定义环境变量:
$ export OPENSSL_ROOT_DIR=/usr/local/opt/openssl/
在执行 make
编译这个库时,会报出另一个问题:
[ 46%] Built target websockets
Scanning dependencies of target test-server-extpoll
[ 47%] Building C object CMakeFiles/test-server-extpoll.dir/test-apps/test-server.c.o
[ 48%] Linking C executable bin/libwebsockets-test-server-extpoll
clang: error: argument unused during compilation: '-pthread'
make[2]: *** [bin/libwebsockets-test-server-extpoll] Error 1
make[1]: *** [CMakeFiles/test-server-extpoll.dir/all] Error 2
这个问题需要修改工程的编译配置文件,具体而言,是修改工程根目录下的 CMakeLists.txt
,移除其中出现的所有 -pthread
标记。
wslay
这是一个 C 语言的 WebSocket 库。
Poco Websocket
POCO C++ 库是一个跨平台的 C++ 网络库。其中包含了 WebSocket 的实现模块。Poco 库是一个比较强大,比较复杂的网络库。
在 Mac OS 上,可以通过执行 build_cmake.sh
来构建,如:
$ ./configure --minimal
$ ./build_cmake.sh
Crow
Crow 是一个 Web 微框架。
这个库在底层依赖于 boost 库,作为异步网络 I/O 库。
websocketpp(WebSocket++)
websocketpp 是 C++ 的 WebSocket 客户端/服务器库。它是一个开源的只包含头文件的 C++ 库,它实现了 RFC6455 WebSocket 协议。它允许向 C++ 程序中集成 WebSocket 客户端和服务器功能。它使用可交换的网络传输模块,包括基于 C++ iostreams 的和基于 Boost Asio 的。
Beast
基于 Boost.Asio 以 C++11 构建的 HTTP 和 WebSocket 库。Boost 项目的 HTTP 和 WebSocket 库。
在以上的 6 个 C/C++ WebSocket 库中,其中有 3 个(Crow、websocketpp(WebSocket++)和 Beast)是基于 Boost 的网络库实现的。
结论
WebSocket 项目 | GitHub 主页 | GitHub star 数 |
---|---|---|
uWebSockets | GitHub 主页 | 9,777 |
libwebsockets | GitHub 主页 | 1839 |
wslay | GitHub 主页 | 327 |
Poco Websocket | GitHub 主页 | 3009 |
Crow | GitHub 主页 | 4611 |
websocketpp | GitHub 主页 | 2692 |
Beast | GitHub 主页 | 1618 |
选择WebSocket 库主要依据如下考量点:
- 运行时的性能;
- API 的易用性;
- 项目的活跃度;
- 文档说明的完备性;
- 运行时的内存用量;
- 项目发展成熟,获得了比较广泛的使用;
- 支持跨 Windows/Mac OSX/ Linux 平台开发;
- 依赖简单,尽量不引入庞大复杂的 C/C++ 开发框架,如 QT、 Boost 和 Poco 这样的 C++ 开发框架;
- 功能的完备性,支持自动的 ping-pong 心跳消息,支持 WebSocket server 端开发,支持传输二进制及文本消息,支持流式输入输出 API。
综合考量上面各项因素,最终选择 uWebSockets 用于实际的项目。
参考资料:
Comparison of WebSocket implementations
JSON RPC 库选型
由之前抓到的 Scratch 的 JSON RPC 消息来看,Scratch 采用的是 2.0 的JSON RPC 协议。JSON RPC Wiki 页描述了各种版本的 JSON RPC 协议,并列出了当前可用的大部分 JSON-RPC 库,其中 C/C++ 库总共有 11 个:jsonrpc-c、jsonrpc、libjrpc、libjson-rpc-cpp、JsonRpc-Cpp、gSOAP、Phobos、qjsonrpc、cxxtools、AnyRPC、jsonrpc-lean。
由于 JSON RPC 协议比较简单,且已经出现了比较长的时间,当前的 JSON RPC 实现的项目基本都处于长久不更新的稳定状态。上面这些 JSON RPC 库中,cxxtools 是为 Unix 和 Linux 编写的 C++ 类库。qjsonrpc 和 Phobos 是为 QT 编写的 JSON RPC 支持库。gSOAP 是商业软件。 jsonrpc-c、jsonrpc 和 libjrpc 实现的太弱。JsonRpc-Cpp 没有考虑过为 Windows 提供支持。AnyRPC 提供了多种 RPC 协议的支持,包括 XML RPC 等。
剩余如下 2 个:
基于如下的考量:
- 跨平台;
- 依赖简单;
- API 使用方便。
选择 jsonrpc-lean 作为我们项目使用的 JSON RPC 库。jsonrpc-lean
的JSON 解析部分由 RapidJSON 支持。
参考文档:
Done.