c++ libwebsocket库应用开发
WebSocket是一种在单个TCP连接上进行全双工通信的协议。允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
一、参考网址:
libwebsockets官网: https://libwebsockets.org/
libwebsockets的API:https://libwebsockets.org/lws-api-doc-master/html/modules.html
https://libwebsockets.org/libwebsockets-api-doc.html
cmake 去除openssl库依赖.vs2010编译.
建立双工通道,接下来就可以进行收发数据, 当连接成功之后,通过不断询问service 是否有回调事件,来处理对应的回调事件.
// ConSoleWebS_Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// Consolelibwebs.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "include/libwebsockets.h"
#include <signal.h>
#include <string.h>
#include <map>
using namespace std;
map<long,string>map_wsi_token;// 存wsi指针为key, token为字符串
static volatile int exit_sig = 0;
#define MAX_PAYLOAD_SIZE 10 * 1024
void sighdl(int sig) {
lwsl_notice("%d traped", sig);
exit_sig = 1;
}
/**
* 会话上下文对象,结构根据需要自定义
*/
struct session_data {
int msg_count;
unsigned char buf[LWS_PRE + MAX_PAYLOAD_SIZE];
int len;
bool bin;
bool fin;
};
static int protocol_my_callback(struct lws* wsi, enum lws_callback_reasons reason, void* user, void* in, size_t len) {
struct session_data* data = (struct session_data*)user;
switch (reason) {
case LWS_CALLBACK_PROTOCOL_INIT:
break;
case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: //这里的wsi中才有url内容
{
char content_length_str[200] = {0};
lws_hdr_copy(wsi,content_length_str,200,(lws_token_indexes)0);
//TODO: 获取最新的mythread->GetNewToken(chartoken); 替换 a2abd43dfooepcxw
//.例如:
//char chartoken[100] = {0};
//mythread->GetNewToken(chartoken);
//if(strstr(content_length_str,chartoken) != NULL)
//{
// map_wsi_token.insert(pair<long,string>(long(wsi),string(chartoken)));
//}
//else
// return -1;
}
break;
case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED:
break;
case LWS_CALLBACK_FILTER_NETWORK_CONNECTION:
break;
case LWS_CALLBACK_WSI_CREATE:
break;
case LWS_CALLBACK_HTTP:
break;
case LWS_CALLBACK_ADD_HEADERS:
break;
case LWS_CALLBACK_FILTER_HTTP_CONNECTION:
break;
case LWS_CALLBACK_ESTABLISHED: // 当服务器和客户端完成握手后
printf("Client connect!\n");
break;
case LWS_CALLBACK_SESSION_INFO:
break;
case LWS_CALLBACK_RECEIVE: // 当接收到客户端发来的帧以后
{
map<long,string>::iterator iter = map_wsi_token.find(long(wsi));
if(iter != map_wsi_token.end())
{
//TODO: 获取最新的mythread->gettoken(char); 替换 a2abd43dfooepcxw
string strtoken = iter->second;
if(strtoken.find("a2abd43dfooepcxw") >= -1)
{
return -1;
}
}
else
{
return -1;
}
// 判断是否最后一帧
data->fin = lws_is_final_fragment(wsi);
// 判断是否二进制消息
data->bin = lws_frame_is_binary(wsi);
// 对服务器的接收端进行流量控制,如果来不及处理,可以控制之
// 下面的调用禁止在此连接上接收数据
lws_rx_flow_control(wsi, 0);
// 业务处理部分,为了实现Echo服务器,把客户端数据保存起来
memcpy(&data->buf[LWS_PRE], in, len);
data->len = len;
printf("recvied message:%s\n", in);
// 需要给客户端应答时,触发一次写回调
lws_callback_on_writable(wsi);
}
break;
case LWS_CALLBACK_SERVER_WRITEABLE: // 当此连接可写时
{
lws_write(wsi, &data->buf[LWS_PRE], data->len, LWS_WRITE_TEXT);
// 下面的调用允许在此连接上接收数据
lws_rx_flow_control(wsi, 1);
}
break;
case LWS_CALLBACK_LOCK_POLL:
case LWS_CALLBACK_UNLOCK_POLL:
break;
case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
map<long,string>::iterator iter = map_wsi_token.find(long(wsi));
if(iter != map_wsi_token.end())
{
map_wsi_token.erase(iter);
}
break;
}
// 回调函数最终要返回0,否则无法创建服务器
return 0;
}
/**
* 支持的WebSocket子协议数组
* 子协议即JavaScript客户端WebSocket(url, protocols)第2参数数组的元素
* 你需要为每种协议提供回调函数
*/
struct lws_protocols protocols[] = {
{
//协议名称,协议回调,接收缓冲区大小
"http", protocol_my_callback, sizeof(struct session_data), MAX_PAYLOAD_SIZE,
},
{
//协议名称,协议回调,接收缓冲区大小
"ws", protocol_my_callback, sizeof(struct session_data), MAX_PAYLOAD_SIZE,
},
{
NULL, NULL, 0 // 最后一个元素固定为此格式
}
};
int _tmain(int argc, _TCHAR* argv[])
{
// 信号处理函数
signal(SIGTERM, sighdl);
struct lws_context_creation_info ctx_info = { 0 };
ctx_info.port = 9002;
ctx_info.iface = NULL; // 在所有网络接口上监听
ctx_info.protocols = protocols;
ctx_info.gid = -1;
ctx_info.uid = -1;
ctx_info.options = LWS_SERVER_OPTION_VALIDATE_UTF8;
// ctx_info.ssl_ca_filepath = "../ca/ca-cert.pem";
// ctx_info.ssl_cert_filepath = "./server-cert.pem";
// ctx_info.ssl_private_key_filepath = "./server-key.pem";
// ctx_info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
//ctx_info.options |= LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
struct lws_context* context = lws_create_context(&ctx_info);
while (!exit_sig) {
lws_service(context, 1000);
}
lws_context_destroy(context);
return 0;
}
c++ libwebsocket库应用开发相关推荐
- c++ libwebsocket库应用开发2
1.向web端发送二进制数据与文本数据时注意 //lws_write(wsi, data->buf+LWS_PRE, isz, LWS_WRITE_BINARY); //lws_write(w ...
- 手把手教你写C语言的动态库的开发
前言 动态库的概念: 动态库提供了一种方法,使进程可以调用不属于其可执行代码的函数.函数的可执行代码位于一个 DLL 文件中, 该 DLL 包含一个或多个已被编译.链接并与使用它们的进程分开存储的函数 ...
- 树莓派UART串口编程--使用wiringPi库-C开发【1-基础应用】
一.串口说明 莓派3B+上UART串口位于GPIO的8脚和10脚,分别为GPIO8=Tx,GPIO10=Rx.在连接外部接口时,需要交换接口,即GPIO8连接到外设的Rx,GPIO10连接到外设的Tx ...
- Android 须知2019流行的框架库及开发语言
Android 须知2019流行的框架库及开发语言 导语 2018 已经悄悄的走了,2019 也已经匆匆的来了,我们在总结过去的同时,也要展望一下未来,来规划一下今年要学哪些新技术.这几年优秀Andr ...
- 预告:公共语言运行库(CLR)开发系列课程(4):COM Interop进阶
这次我主要讲RCW的原理,生命周期,引用计数,套间,System.__ComObject,事件调用原理等内容.CCW由于时间限制就不涉及了,毕竟大家还是以使用RCW为主. 感兴趣的朋友可以在下面注册: ...
- STM32F103C8T6基础开发教程(HAL库)—开发环境配置
STM32F103C8T6基础开发教程目录 STM32F103C8T6基础开发教程(HAL库)-开发环境配置 STM32F103C8T6基础开发教程(HAL库)-Keil添加注释的快捷键 STM32F ...
- Maven环境下测试库和开发库的配置策略以及支持工具
在项目的开发和测试上,团队往往有这样一些情况和要求: 1. 只要是走单元测试,必然要清库 2. 开发人员不想每次重新构建都从一个空库开始重新输入数据,他们希望能够使用一个已有的库 3. 如果新版本的数 ...
- 通过python各种开源库,开发一个适合大部分公司测试项目框架,确定名字AutoTestProjects
通过python各种开源库,开发一个适合大部分公司测试项目框架,确定名字AutoTestProjects 一,简介 1.目前市场上的框架一般都需要码农进行编写,对测试小白非常的不友好,而且现在整个IT ...
- 基于WEB的多媒体素材管理库的开发与应用,免费分享
今天将为大家分析一个基于WEB的多媒体素材管理库的开发与应用(进入21世纪以来,随着计算机信息技术的发展,在世界范围内的教育领域中,多媒体技术已经被作为一种新兴的教学手段而广泛应用,对于计算机得辅助教 ...
最新文章
- 差分约束系统——建模与求解
- ce5e.cn fadian.php,空包网 PHP mysql
- c+ +三角函数_C ++中的三角函数
- 《SpringCloud超级入门》使用Eureka编写服务消费者《十一》
- 10 个令人惊喜的 jQuery 插件推荐
- .NET BackgroundWorker的一般使用方式
- 公众号菜单 点击推送图片素材_公众号菜单栏如何设置
- EnterpriseDb公司的Postgres Enterprise Manager 安装图解
- 应用安全 - Web安全 - 逻辑漏洞整理
- ADF文件数据结构解析和ADF文件读写
- 嵌入式linux地图,基于嵌入式Linux的MapInfo格式地图显示
- 读《C专家编程》笔记-关于内存泄漏
- tomcat内存溢出全记录
- 淘宝客微信机器人搭建教程分享
- Java获取IP归属地
- cajviewer阅读器打不开怎么解决
- IoT原型开发利用现成的单板设计---凯利讯半导体
- Overload和Override
- vs 2019 自带 反编译 与 Reflector 反编译工具比较
- 帝国CMS采集插件哪个好用?帝国CMS采集文章教程
热门文章
- 堃博医疗创上市以来新低:年内跌幅超八成,市值累计蒸发90亿港元
- 大数据学习线路及各阶段学习书籍推荐
- DT时代,大数据分析都包含了哪些技术?
- Waifu2x-Extension-GUI 图片 GIF 视频 人工智能放大与降噪(超分辨率) v1.50.2 更新
- Java实现的LU分解,高斯消去法求线性方程组的解
- 避免繁琐步骤,在Ubuntu22.04安装cuda、cudnn及pytorch
- 智能猪场APP开发有哪些功能特点?
- 深入理解--ES之倒排索引
- Java 编写Validator验证器
- 用随机投点法计算pi值matlab,(原创精品)用随机投点法计算π值【Compute π with dartpoint randomly】.doc...