当前位置: 首页 > news >正文

网站建设图片流程图我的家乡网页制作素材

网站建设图片流程图,我的家乡网页制作素材,网站开发目录过多的缺点,企业网站托管哪家好libwebsockets websocket客户端基本流程网上都有,我只额外优化了重连机制。 在服务器异常断开时不触发LWS_CALLBACK_CLOSED或LWS_CALLBACK_CLIENT_CONNECTION_ERROR,导致无法自动重连 通过定时检查链接是否可写入判断链接是否有效 // 判断wsi是否可用if …

libwebsockets
websocket客户端基本流程网上都有,我只额外优化了重连机制。
在服务器异常断开时不触发LWS_CALLBACK_CLOSEDLWS_CALLBACK_CLIENT_CONNECTION_ERROR,导致无法自动重连
通过定时检查链接是否可写入判断链接是否有效

 // 判断wsi是否可用if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() -last_time) > detect_dup){if (lws_callback_on_writable(wsi) <= 0){std::cerr<< "[WebSocket] Connection failed, retrying in 3s..." << std::endl;wsi = nullptr;// continue;}last_time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();}

完整代码

#ifndef MYWSCLIENT_H
#define MYWSCLIENT_H#pragma once#include <iostream>
#include <thread>#include <libwebsockets.h>
#include <atomic>
#include <functional>
#include <mutex>
#include <condition_variable>/*
异步启动WebSocket
自动重连
*/
class MyWSClient
{
public:using MessageCallback = std::function<void(const std::string &)>;MyWSClient(const std::string &url, int port, const std::string &path, MessageCallback onMessage = nullptr);~MyWSClient();void start();void stop();void sendMessage(const std::string &message);private:std::string url;std::string path;int port;int detect_dup = 3; // sMessageCallback onMessageCallback;struct lws_context *context;struct lws *wsi;std::thread wsThread;std::atomic<bool> running;std::mutex sendMutex;std::vector<std::string> sendQueue;void run();void reconnect();static int callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len);static struct lws_protocols protocols[];
};#endif
#include "MyWSClient.h"#include "spdlog/spdlog.h"using namespace std;MyWSClient::MyWSClient(const std::string &url, int port, const std::string &path, MessageCallback onMessage): url(url), port(port), path(path), onMessageCallback(onMessage), context(nullptr), wsi(nullptr), running(false) {}MyWSClient::~MyWSClient() { stop(); }void MyWSClient::start()
{running = true;wsThread = std::thread(&MyWSClient::run, this);
}void MyWSClient::stop()
{running = false;if (context){lws_context_destroy(context);context = nullptr;}if (wsThread.joinable()){wsThread.join();}
}void MyWSClient::sendMessage(const string &message)
{if (!wsi){std::cout << __func__ << " error send, ws server not connected" << std::endl;return;}std::lock_guard<std::mutex> lock(sendMutex);sendQueue.push_back(message);if (wsi){int res = lws_callback_on_writable(wsi);std::cout << __func__ << " send :" << message << ", res:" << res << std::endl;}
}
void MyWSClient::run()
{struct lws_context_creation_info ctx_info = {};struct lws_client_connect_info conn_info = {};ctx_info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;ctx_info.port = CONTEXT_PORT_NO_LISTEN;ctx_info.protocols = protocols;context = lws_create_context(&ctx_info);if (!context){std::cerr << "[WebSocket] Failed to create context" << std::endl;return;}conn_info.context = context;conn_info.address = url.c_str();conn_info.port = port;conn_info.path = path.c_str();conn_info.host = url.c_str();conn_info.origin = url.c_str();conn_info.protocol = "ws";conn_info.ssl_connection = LCCSCF_USE_SSL |LCCSCF_ALLOW_SELFSIGNED |LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK |LCCSCF_ALLOW_EXPIRED;conn_info.userdata = this;long last_time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();while (running){if (!wsi){std::this_thread::sleep_for(std::chrono::seconds(3));std::cout << "[WebSocket] Attempting to connect..." << std::endl;wsi = lws_client_connect_via_info(&conn_info);}// 判断wsi是否可用if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() -last_time) > detect_dup){if (lws_callback_on_writable(wsi) <= 0){std::cerr<< "[WebSocket] Connection failed, retrying in 3s..." << std::endl;wsi = nullptr;// continue;}last_time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();}if (lws_service(context, 0) < 0){std::cerr<< "[WebSocket] lws_service failed" << std::endl;}}lws_context_destroy(context);
}void MyWSClient::reconnect()
{stop();std::cerr<< "[WebSocket] reconnect, retrying in 3s..." << std::endl;run();
}int MyWSClient::callback(lws *wsi, lws_callback_reasons reason, void *user, void *in, size_t len)
{MyWSClient *client = (MyWSClient *)lws_wsi_user(wsi);switch (reason){case LWS_CALLBACK_CLIENT_ESTABLISHED:{std::cout << "[WebSocket] Connected to server" << std::endl;lws_callback_on_writable(wsi); // 请求写入break;}case LWS_CALLBACK_CLIENT_RECEIVE:{if (client->onMessageCallback){client->onMessageCallback(std::string((char *)in, len));}break;}case LWS_CALLBACK_CLIENT_WRITEABLE:{std::lock_guard<std::mutex> lock(client->sendMutex);if (!client->sendQueue.empty()){std::string message = client->sendQueue.front();client->sendQueue.erase(client->sendQueue.begin());std::cout << __func__ << " send:" << message << std::endl;// 确保 LWS_PRE 字节已预留unsigned char buf[LWS_PRE + 1024] = {0};int msgLen = message.size();memcpy(buf + LWS_PRE, message.c_str(), msgLen);int sent = lws_write(wsi, buf + LWS_PRE, msgLen, LWS_WRITE_TEXT);if (sent < 0){std::cerr << __func__ << "lws_write failed!" << std::endl;}// 如果还有数据,继续请求写入if (!client->sendQueue.empty()){lws_callback_on_writable(wsi);}}break;}case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:{std::cerr << "[WebSocket] Connection error: " << (in ? (char *)in : "unknown") << std::endl;client->wsi = nullptr;// client->reconnect();break;}case LWS_CALLBACK_CLOSED:{std::cout << "[WebSocket] Connection closed" << std::endl;client->wsi = nullptr;// client->reconnect();break;}default:break;}return 0;
}// 定义协议数组
struct lws_protocols MyWSClient::protocols[] = {{"ws", MyWSClient::callback, 0, 4096},{nullptr, nullptr, 0, 0}};
http://www.dtcms.com/a/432019.html

相关文章:

  • **全息显示技术的发散创新与深度探索**一、引言随着科技的飞速发展,全息显示技术已成为显示领域的一大研究热点。本文将带你
  • 旅游网站推广方案植物染企业解决方案
  • 深度学习基础知识-Transformer基础
  • 网站建设关键词排名网站中所有标签
  • JVM虚拟机栈溢出与堆溢出有什么区别?
  • 新奇特:负权重橡皮擦,让神经网络学会主动遗忘
  • 成都公园城市建设局网站中山大良网站建设
  • 04、Python从入门到癫狂:对象
  • 云南昆明网站建设公司网站开发环境搭建
  • 营销网站策划方案爱南宁下载安装
  • 钦州网站推广郑州网课老师
  • h5网站建设h精准营销的好处
  • AI从技术到生产力的跨越
  • 庐江县住房和城乡建设局网站苏州吴中区住房和城乡建设局网站
  • 一家专门做母婴的网站杭州百度网站建设
  • 企业营销网站开发建设专家百度云服务器做网站稳定吗
  • 广东一站式网站建设费用建设网站要不要投资钱
  • 20251001——在ANSYS MAXWELL中如何对二维平面图形进行镜像
  • 【LattePanda Mu 开发套件】AI 图像识别网页服务器
  • 昆山网站排名优化wordpress建站安全吗
  • 网站和app设计区别小程序开发定制外包15
  • 网站开发工作好找吗网站开发培训深圳
  • leetcode2.两数相加
  • 上海跨境电商网站制作wordpress 文章设置
  • 网站推广服务 商务服务一页网站首页图如何做
  • 网站建设相关文章商业网站的创建程序
  • 【手撕机器学习 04】手撕线性回归:从“蒙眼下山”彻底理解梯度下降
  • 七个php源码下载的网站网站建设通报
  • 网络技术与网站建设模板网站建设代理商
  • 湘潭网站建设优化技术2 网站内部链接优化