日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ libwebsocket库应用开发

發布時間:2023/12/20 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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库应用开发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。