Socket.IO-Client-cpp的使用——C++

前言

Socket.IO C++基于Boost和WebSocket++,可在多平台上工作(跨平台)。此通信类似于websocket,但是不通用于websocket。

Sockect.io 与Websocket的区别

我在知乎上看到说明两者的区别,感觉比较详细

WebSocket和Socket.io之间的区别(译) - 知乎 (zhihu.com)

Sockect.IO编译

Socket.IO-Client-cpp编译——C++_十年之少的博客-CSDN博客

代码说明

我是比照着 官方的给的示例(socket.io-client-cpp-master/examples/QT/SioChatDemo)进行学习的,官方的示例说明网址是Socket.IO C++ | Socket.IO

  • 在.h文件上设置命名空间
using namespace sio;
  • 获取套接字(socket),可获取含有命名的套件字,具体看需求;
socket::ptr sock = _io->socket();
// socket::ptr sock = _io->socket("nsp");
  •  监听套接字的事件,如新消息、用户加入、用户离开等;需要用到socket::on函数,他有两种形式,如下

 typedef std::function<void(const std::string& name,message::ptr const& message,
                bool  need_ack, message::list& ack_message)> event_listener_aux;
        
 typedef std::function<void(event& event)> event_listener;

 void on(std::string const& event_name,event_listener const& func);
        
 void on(std::string const& event_name,event_listener_aux const& func);

   很明显,示例里用的是第二种形式,回调函数的格式必须是:

   void  funcName (const std::string& name,message::ptr const& message,bool need_ack,

          message::list& ack_message)

   name :消息名

   message:消息数据句柄

   need_ack:是否需要确认

   ack_message:确认的消息

    #ifdef WIN32
    #define BIND_EVENT(IO,EV,FN) \
      do{ \
          socket::event_listener_aux l = FN;\
          IO->on(EV,l);\
        } while(0)

    #else
    #define BIND_EVENT(IO,EV,FN) \
      IO->on(EV,FN)
    #endif
    

    void MainWindow::MainWindow(...)
    {
       ...

       using std::placeholders::_1;
       using std::placeholders::_2;
       using std::placeholders::_3;
       using std::placeholders::_4;

       BIND_EVENT(sock,"new message",std::bind(&MainWindow::OnNewMessage,
                 this,_1,_2,_3,_4));

       ...
    }

    void MainWindow::OnNewMessage(std::string const& name,message::ptr const& data,
    bool hasAck,message::list &ack_resp)
   {

       if(data->get_flag() == message::flag_object)
       {
           std::string msg = data->get_map()["message"]->get_string();
           std::string username = data->get_map()["username"]->get_string();
           QString label = QString::fromUtf8(username.data(),username.length());
           label.append(" : ");
           label.append(QString::fromUtf8(msg.data(),msg.length()));
           QListWidgetItem *item= new QListWidgetItem(label);
           Q_EMIT RequestAddListItem(item);
       }
    }
  •    监听客户端的某些事件,如客户端的关闭连接等;
_io->set_close_listener(std::bind(&MainWindow::OnClosed,this,_1));


void MainWindow::OnClosed(client::close_reason const& reason)
{
    Q_EMIT RequestToggleInputs(false);
}
  • 创建连接
#define kURL "http://localhost:3000"

_io->connect(kURL);

  • 发送消息:用socket的方法emit进行发送 
void emit(std::string const& name, message::list const& msglist = nullptr,           std::function<void (message::list const&)> const& ack = nullptr);
void MainWindow::OnConnected(std::string const& nsp)
{
    QByteArray bytes = m_name.toUtf8();
    std::string nickName(bytes.data(),bytes.length());
    _io->socket()->emit("add user", nickName);
}

运行程序

要想玩转示例程序,还需要注意各方努力:

  • 客户端

   1>检查pro文件:在运行前 需要检查SioChatDemo.pro文件所配置的动态库位置;

   2>确认填写的服务器的地址;

  •  服务器

   1>下载服务器代码:https://github.com/Automattic/socket.io/tree/master/examples/chat

   2>按照命令运行服务器: 

$ npm i
$ npm start

   当命令行出现:Server listening at port 3000,表示运行成功。

效果图

结束语

此次学习Socket.IO真是有点费劲,虽然代码看着挺清楚,但是环境这块真的费大劲了:编译客户端库、编译Boost、下载服务器代码及运行,其中的弯路不必说。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值