C++之socket.io编译使用

计弘
2023-12-01

1. 什么是socket.io

  • Socket.IO 实现了实时双向的基于事件的通讯机制。旨在让各种浏览器与移动设备上实现实时app功能,模糊化各种传输机制。

2. 开发环境配置

socket.io的编译需要安装如下依赖环境

  • cmake
  • rapidjson
  • boost
  • websocketpp

2.1 获取socket.io的源码

  • git clone https://github.com/socketio/socket.io-client-cpp.git

2.2 cmake安装

  • sudo apt-get install cmake

2.3 boost安装

2.3.1 获取源码

  • https://sourceforge.net/projects/boost/files/boost/ 把源码下载下来(boost_1_74_0.tar.bz2)

2.3.2 解压编译下载

  • tar -xvf boost_1_74_0.tar.bz2
  • cd boost_1_74_0/
  • ./bootstrap.sh
  • ./b2

2.4 rapidjson下载

socket.io的源码的目录结构如下:
├── API.md
├── boost_1_74_0.tar.bz2
├── BOOST.md
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── CMakeLists.txt
├── examples
├── INSTALL_IOS.md
├── INSTALL.md
├── lib
├── libsioclient.a
├── libsioclient_tls.a
├── LICENSE
├── Makefile
├── README.md
├── src
└── test

cd lib
.
├── rapidjson
└── websocketpp

把下载下来的源码放在rapidjson中

git clone https://github.com/Tencent/rapidjson.git

2.5 websocketpp下载

  • 和rapidjson下载同理进入把websocketpp下载的内容放到websocketapp中
  • git clone https://github.com/zaphoyd/websocketpp.git
最后lib中的目录结构如下:
├── rapidjson
│   ├── appveyor.yml
│   ├── bin
│   ├── CHANGELOG.md
│   ├── CMakeLists.txt
│   ├── CMakeModules
│   ├── contrib
│   ├── doc
│   ├── docker
│   ├── example
│   ├── include
│   ├── include_dirs.js
│   ├── library.json
│   ├── license.txt
│   ├── package.json
│   ├── rapidjson.autopkg
│   ├── RapidJSONConfig.cmake.in
│   ├── RapidJSONConfigVersion.cmake.in
│   ├── RapidJSON.pc.in
│   ├── readme.md
│   ├── readme.zh-cn.md
│   ├── test
│   ├── thirdparty
│   └── travis-doxygen.sh
└── websocketpp
    ├── changelog.md
    ├── cmake
    ├── CMakeLists.txt
    ├── COPYING
    ├── docs
    ├── Doxyfile
    ├── examples
    ├── readme.md
    ├── roadmap.md
    ├── SConstruct
    ├── test
    ├── tutorials
    ├── websocketpp
    └── websocketpp-config.cmake.in

2.6 编译socket.io

cmake -DBOOST_ROOT:STRING=/home/fzj/socketio/boost_1_74_0(boost安装的位置)  -DBOOST_VER:STRING=1.74.0(boost版本) .

make

make install

最后会生成build,里面有
├── include(静态库对应的头文件)
│   ├── sio_client.h
│   ├── sio_message.h
│   └── sio_socket.h
└── lib(socket.io的静态库)
    └── Release
        ├── libboost_date_time.a
        ├── libboost_random.a
        ├── libboost_system.a
        ├── libsioclient.a
        └── libsioclient_tls.a

3. socket.io测试

3.1 建立测试程序

//把上面编译出来的头文件拉倒当前测试程序的文件夹中

#include <iostream>
#include "sio_client.h"
#include "sio_socket.h"
#include "string.h"

using namespace std;
using namespace sio;


int main()
{

    sio::client h;
    std::string nickName = "123"

    h.connect("https://域名:端口");
    h.socket()->emit("readyToStream", nickName);

    cout << "Hello, world!" << endl;
    return 0;
}

g++ sockiotest.cpp  -o test /home/fzj/socketio/socket.io-client-cpp/build/lib/Release/libsioclient.a -lpthread  
[2020-09-24 02:15:11] [connect] Successful connection
[2020-09-24 02:15:11] [error] handle_read_http_response error: websocketpp.transport:7 (End of File)

编译后出现该情况,经上网查询后,发现这个问题是TLS的问题,如果是https建议我们使用libsioclient_tls.a这个库,使用这个库确保你虚拟机上安装有openssl。(经常测试无论http还是https还是一样的效果)

更改使用libsioclient_tls.a这个库后会报另外的错误
g++ sockiotest.cpp  -o test /home/fzj/socketio/socket.io-client-cpp/build/lib/Release/libsioclient_tls.a -lpthread  -lm -lssl -lcrypto

[2020-09-24 02:10:39] [connect] Successful connection
[2020-09-24 02:10:39] [error] handle_transport_init received error: TLS handshake failed
[2020-09-24 02:10:39] [info] asio async_shutdown error: asio.ssl:336462231 (shutdown while in init)

经过3个小时的尝试和不断的努力,终于找到了答案,原始是TLS的版本问题,客户端和服务端不同
于是修改socket.io的源码

1. 找到sio_client_impl.cpp原文件(/src/internal/sio_client_impl.cpp)
2. 打开文件/src/internal/sio_client_impl.cpp
3. 找到源码如下位置
#if SIO_TLS
    client_impl::context_ptr client_impl::on_tls_init(connection_hdl conn)
    {
        //!更改boost :: asio :: ssl :: context :: tlsv1 -----> boost :: asio :: ssl :: context :: tlsv12
        context_ptr ctx = context_ptr(new  boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
        boost::system::error_code ec;
        ctx->set_options(boost::asio::ssl::context::default_workarounds |
                             boost::asio::ssl::context::no_sslv2 |
                             boost::asio::ssl::context::single_dh_use,ec);
        if(ec)
        {
            cerr<<"Init tls failed,reason:"<< ec.message()<<endl;
        }
        
        return ctx;
    }
#endif
4. 保存文件重新编译安装,参照2.6 编译socket.io
5. 重新测试,测试成功,已经完成连接
[2020-09-24 02:56:13] [connect] Successful connection
[2020-09-24 02:56:13] [connect] WebSocket Connection 129.204.161.74:8091 v-2 "WebSocket++/0.8.2" /socket.io/?EIO=4&transport=websocket&t=1600941373 101

 类似资料: