首页

文章

c++ websocketpp 怎么用

发布网友 发布时间:2022-04-20 04:37

我来回答

1个回答

热心网友 时间:2022-04-24 15:33

首先:在我们是要使用C++搭配现有的函数库来开发的,所以不太适合使用一般的网站服务器方案;而在稍微评估了一下后,后来是决定使用「WebSocket++」这个函数库,来做为C++环境的WebSocket Server开发方案。
WebSocket++的官方网站是:http://www.zaphoyd.com/websocketpp,他是采用BSD License的OpenSource、跨平台函数库,文件则都放在Github上(网页)。他目前最新的版本是0.3.x,在Github上要切换到「experimental」这个brahch;而这个版本的WebSocket++基本上是使用C++11以及Boost C++ Libraries里的ASIO(官网)来实作的Header -Only的函数库,所以在使用前不需要特别去建置这个函数库、只要在需要时去include他的Header档就可以了,相当地方便。
然后在WebSocket 的功能方面,他除了有提供Server 端的功能外,也可以用来开发Client 端的程序,算是相当地完整;虽然他的板号还在0.3,好像还很新,不过实际上功能应该算是够用了~
1.文件准备
  如果要使用WebSocket++ 的话,基本上就是先到GitHub 上0.3.x 这个分支:https://github.com/zaphoyd/websocketpp/tree/experimental去把文件下载下来。而下载下来的文件里面,「websocketpp」这个文件夹,就是要使用这个函数库时,所有需要的文件了~而文件的部分,则是要连到他的网页(链结)去看,内容不算很完整,Heresy算是看着范例程序和原始码写出来的;这点算是Heresy觉得这个函数库做的比较差一点的地方,不过考虑到现在还是0.3版,也就不要要求太多了。
  另外,由于他是基于Boost ASIO来开发网络的功能,所以也必须要下载Boost C++ Libraries来使用;Boost的官方网站是:http://www.boost.org/。
  而如果有需要用到TLS的加密连线的话,应该是会需要使用OpenSSL这个函数库(官网);如果不打算做加密连线的话,基本上是可以跳过这个函数库的。(Heresy没试过这部分)
2.基本概念
  WebSocket++的基本使用说明,可以参考《Building a program with WebSocket++》这份文件。Heresy这边算是整理一下,自己玩过后的想法。
  首先,要使用WebSocket++ 来开发程序的时候,基本上要include 两种文件,一种是用来做组态设置(config)的,一种则是用来决定要开发的程序的脚色类型(Role)的。
  Role
  在Role 的部分,主要就是分成Server 和Client 两种;Server 就是用来开发WebSocket 服务器的,而Client 则是可以用来开发C++ 的WebSocket 的用户端程序、连线到其他的??WebSocket Server 做数据的存取。
  如果要建立Server 端的程序的话,就是要include server 用的header 档:
  #include <websocketpp/server.hpp>
  而之后则是就可以建立出websocketpp::server<>的物件,拿来做操作。
  如果是要建立Client 端程序的话,则是要include client 的header 档:
  #include <websocketpp/client.hpp>
  之后则是建立出websocketpp::client<>的物件来做连线。
  而WebSocket++的server或client这两种类别,都是template的class,在建立时也需要指定要使用的config才可以。
  Config
  Config 的部分,WebSocket++ 主要提供了三种类型:
  config::core
  config::asio
  config::asio_tls
  上面这三种类型,在WebSocket++是不同的结构,,config::core基本上是提供有限功能的设置,相对的他只会用到C++11的功能。而config::asio则是使用Boost ASIO做基础来提供完整的功能;config::asio_tls则是config::asio再加上TLS的连线加密功能。
  而根据组合的不同,不同的config也需要include websocketpp/config的目录下、不同的header档:
  
  Server
  Client
  core
  core.hpp
  core_client.hpp
  asio
  asio_no_tls.hpp
  asio_no_tls_client.hpp
  asio_tls
  asio.hpp
  asio_client.hpp
  而如果是以要建立一个使用Boost ASIO、没有TLS加密的Server的话,基本上就是要include
  asio_no_tls.hpp
  #include <websocketpp/config/asio_no_tls.hpp>
  其他的组合,也可以依此类顶。
  Endpoint
  在决定要include 哪两个文件后,接下来就可以在程序里面,建立出需要使用的WebSocket++ 物件了。
  如果是要建立使用Boost ASIO、没有TLS 加密的Server 的话,基本上要include 的文件就是:
  #include <websocketpp/server.hpp>
  #include <websocketpp/config/asio_no_tls.hpp>
  而在控制用的物件的部分,则就是:
  websocketpp:: server <websocketpp::config:: asio > mServer;
  之后,所有的功能就都是针对mServer这个物件进行操作。而在WebSocket++里面,则是把它称为「endpoint」;通过组合出不同的endpoint,就可以实作不同的功能了。
  Server 的范例
  基本上,因为Heresy的目的是要建立一个WebSocket Server让网页来连线,所以这边就只讲Server的部分了~而实际上,在《Building a program with WebSocket++》里,官方就有提供一个很简单的使用范例了~他的源代码如下:
  #include <iostream>
  
  #include <websocketpp/config/asio_no_tls.hpp>
  #include <websocketpp/server.hpp>
  
  typedef websocketpp:: server <websocketpp::config:: asio > server ;
  void on_message(websocketpp:: connection_hdl hdl , server :: message_ptr msg )
  {
  std::cout << msg ->get_payload() << std::endl;
  } int main()
  { server print_server;
  
  print_server.set_message_handler(&on_message);
  print_server.init_asio();
  print_server. listen(9002);
  print_server.start_accept(); print_server.run ();
  }

  在这个范例里面,他是通过websocketpp:: server <websocketpp::config:: asio >这个Endpoint,来建立一个使用Boost ASIO、没有TLS加密的WebSocket Server。这个server程序在执行后,会持续去监听port 9002,当有信息传递进来的时候,就会触发到on_message()这个函数、并把接到的信息输出到命令提示字符的窗口上。
  如果想要测试连线的话,可以考虑用 WebSocket.org 提供的
  不过实际上,由于WebSocket++ 本身也有log 的功能,所以除了收到的信息会被输出之外,还有很多纪录用的信息,也都会被输出在画面上,看起来可能会有点杂乱就是了。
  另外,由于这个范例程序,只会从client接收信息,并不会传送数据给Server端,所以Echo Text的Log里面,并不会像连到ws:// echo.websocket.org
  在源代码的地方,首先就是建立出一个endpoint的server物件print_server,用来做后续的操作。
  而在建立出print_server后,接下来要做的事情,包括了:
  初始化ASIO
  调用init_asio()这个函数,初始化内部的Boost ASIO的io_service(官网),作为后续网络连线等功能之使用。
  设置连接埠
  调用listen()这个函数,指定要监听的连接埠;这边是设置成9002。
  而如果系统上有多个网卡的话,默认会监听所有的网络介面;如果需要的话也可以特别指定要针对哪个介面做监听。
  开始接受连线
  调用start_accept()开始接受输入。
  进入主循环
  调用run(),进入WebSocket++ Server的主循环。
  之后程序就会进入主循环,直到Server 被停下来。
  那要怎么处理连线进来的信息呢?WebSocket++是通过提供各种「Handler」(callback function),来做事件的处理;在官方网站上,有列出可以使用的handler列表(页面)。
  而在这个范例里,则是通过set_message_handler(),来设置当Server收到信息时,要执行的callback function,这里就是on_message()这个函数;这也是一般来说,一定会用到的callback function 。
  而message handler 的callback function,会收到两个数据:
  一个是websocketpp::connection_hdl型别的数据,是用来识别目前的连线用的;如果之后要传送信息给client的话,就必须要通过这个物件,来设置要把信息传送给谁。而如果有需要的话,也可以藉由server<>的get_con_fromhdl()来取得触发这个 ??事件的连线、以及他的资讯。
  第二个资讯,则是websocketpp::server<>::message_ptr,里面储存的是传递进来的信息。一般来说,这会通过他的get_payload()函数,来取得传递进来的信息,而得到的数据,会是const string&。不过由于WebSocket也有可能是传递非文字的binary数据,所以可能会需要通过 get_opcode()这个函数,来辨别传递进来的数据的形式。
  而在这个范例里面,on_message()这个函数,就是很单纯地把街道的资讯,通过iostream做输出了~
  在网页上的这个范例里面,这个Server只有做接收的功能,并不会送信息给Client端。那如果要送信息给client端要怎么做呢?基本上就是调用server<>的send()这个函数就可以了。
  在官方的example文件夹里,有个echo_server的目录,里面的echo_server.cpp
  而他送出数据的方法,就是:
  s->send(hdl, msg->get_payload(), msg->get_opcode());
  这边可以看到,要调用sned()这个函数来传递数据,基本上是需要给他三个参数:
  websocketpp::connection_hdl的物件,让Server知道是要传给哪个client。
  要传递的数据,这边就是直接把收到的信息(msg->get_payload())再传出去;实际上send()有提供不同的介面,实际的数据型别可以是const void*或const string&。
  最后,则是要有一个opcode,来指定要传 ??递的资讯的形式;如果是纯文字的话,基本上可以直接指定websocketpp::frame::opcode::TEXT。
  而这个范例程序在执行後,如果一样使用 WebSocket.org 的 来测试的话,就可以发现他的功能和 WebSocket.org 测试用的 ws://echo.websocket.org
  Windows / Visual Studio 上的问题
  上面基本上就是WebSocket++ 使用上的基本用法。不过实际上,这样的源代码,在Heresy 这边的Windows + Visual Studio 2010 / 2012,都是没办法正确建置的。
  最主要的问题,基本上应该算是VC++ 本身对Boost C++ Library 的支援性问题吧…在Heresy 测试的结果是发现,如果希望在VisualStudio 2010 或2012 上使用的WebSocket++ 的话,有部分的功能??必须要强制让WebSocket++ 去使用C++ 11 的内建函数库,而不要去使用Boost 的版本。
  设置的方法,可以参考官方的《C++11 Support》这页。以Heresy这边的测试来说,至少functional和memory两个函数库,是需要使用C++11 STL的版本才行的;也就是说,必须要加上_WEBSOCKETPP_CPP11_MEMORY_和_WEBSOCKETPP_CPP11_FUNCTIONAL_这两个定义(因为MSVC不支援完整的C++11,所以不能直接用_WEBSOCKETPP_CPP11_STL_)。
  但是,在加上这两个定义后,实际上会产生另一个问题,那就是std::min()和巨集版本的min()冲到的问题(参考);这个问题,比较简单的方法,就是在再额外定义一个NOMINMAX,来取消掉巨集版本的min()和max()了。
  所以,实际上要让上面的程序可以正常运作,一个方法就是在原始码的一开始、include WebSocket++ 的Header 之前,先加上下面三行:
  #define NOMINMAX
  #define _WEBSOCKETPP_CPP11_FUNCTIONAL_
  #define _WEBSOCKETPP_CPP11_MEMORY_
  或是在VC的专案属性的「组态属性」里面,找到「C/C++」的「前置处理器」,在「前置处理气定义」的栏位里面,加上「NOMINMAX;_WEBSOCKETPP_CPP11_FUNCTIONAL_;_WEBSOCKETPP_CPP11_MEMORY_」了。
  理论上,这两种方法应该都可以让MSVC可以正确地建置上面的范例程序。而这个问题Heresy也有回报给作者了(链结),就看之后有没有办法修正吧。
  另外,Heresy在使用Visual Studio 2012的时候,虽然可以正确编译了,可是在执行阶段,则是会当掉。稍微追了一下源代码后,发现应该是Visual Studio 2012的std::strftime()这个函数(MSDN)有问题所造成的。
  主要的问题是发生在 logger/ basic.hpp这个文件,里面定义的get_timestamp()这个函数里面有透 ??过std::strftime()来打印出目前的时间,以做为纪录之用;而他定义的输出字串,则是一个长度30的C字串buffer。
  由于他有试着输出时区的资讯(%z),而在Visual Sutdio里,如果在台湾的环境的话,他会是一个「台北标准时间」这样的文字;而这样的文字,再加上前面的时间资讯的会,就导致整个结果会超过30个字符。而在这个状况下,Visual Studio 2010只是会无法输出,但是在Visual Studio 2012,却可能是让程序整个当掉… orz
  而解决方法呢?基本上应该是两种,一个是把buffer的大小改大、例如把它改成40(要改两个地方,一个是105行、一个是111行,参考),这样可以让字串够长、不会出问题;另一种方法,则是把105行里定义的时间格式字串「"%Y-%m-%d %H:%M:%S%z"」,最后面的「%z」拿掉,这样就不会去处理时区的资讯,也就比较不容易出问题了。

  最后:这篇大概就这样了。内容,算是对WebSocket++ 的极简单介绍的~实际上,由于官方文件实在不足,所以学习起来有点累;不过,至少已经成功地用WebSocket++ 完成第一个WebSocket 的Server 端程序了~接下来,看看有什么特殊的想法,会再做补充吧。
八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 高分!换显卡nvidia控制面板被我卸了,重新安装显卡驱动后没了nvidia控... 我的nvidia控制面板被卸载了 怎么找回啊 卸载后 这个画面看着很奇怪_百 ... 李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 如何使用websocket压力并发测试工具 怎么样使websocket的兼容行提高,使其兼容ie8、火... 在学websocket 时 遇到问题,没有解决。 PLC有什么功能,起什么作用的? S7-200系列PLC有哪有基本编程元件? fx2n系列可编程控制器的编程元件有哪几种 三菱公司的FX2N系列PLC有哪些编程元件 PLC有哪些基本编程原件? 三菱fx系列plc的软元件主要有哪些 S7-200系列PLC有哪几种编程元件? 三菱plc元件有哪些 FX系列PLC的编程软元件有哪些 1、PLC的编程元件有哪些 plc的6个编程元件 PLC的软元件有哪些 三菱fx系列plc有哪几类编程元件 plc常用软元件有哪些 申请健康码一次,以后出门可以直接用吗?申请的健康吗?以后出门怎么用? PLC内部主要元器件? 1.plc的编程元件有哪些 firefox使用 websocket 报无法建立到 ws://服务器... Windows未成功关闭。如果这是由于系统无响应,或者... 浏览器不支持websocket怎么办 websocket client怎样维持心跳,有没有具体的栗子 为什么我写的websocket通信,没有调用onopen直接调... 罗非是什么鱼? 15一18度可以钓罗非钓多深 我家鱼塘很多小罗非怎么办 野钓罗非用什么饵料好 罗非喜欢吃什么饵料? 秋季钓罗非鱼用什么味型饵料 野钓如何钓大罗非 罗非鱼为什么叫"罗非"鱼? 罗非最喜欢吃什么 请问钓罗非如何打窝? 成语不什么好什么? 黄泉杂货铺罗非身份是什么? 不什么好什么的成语 钓罗非鱼如何配制药酒 不什么好什么?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com