libwebsockets入门

news2024/12/23 12:00:35

WebSocket是一种在单个TCP连接上进行全双工通讯的协议,用于在Web客户端和服务器之间建立持久连接,进行实时通信。它是HTML5开始提供的一种通讯方式,通过使用WebSocket连接,web应用程序可以执行实时的交互,而不是以前的轮询方式。一个WebSocket连接是独立的TCP连接,异步的、双向的、全双工的消息传递实现机制。

特点

WebSocket具有以下特点:

  • 持久连接:在HTTP协议的基础上,WebSocket实现了长连接,即服务器和客户端之间可以保持长时间的通信状态,避免了频繁建立和断开连接的开销。
  • 全双工通信:WebSocket允许服务器和客户端之间任意时刻发送消息,实现了真正的双向通信。
  • 协议切换:WebSocket协议在HTTP协议的基础上升级实现,兼容性良好,可以在使用同样域名和端口的情况下,升级到WebSocket协议。
  • 轻量级:WebSocket的数据格式比较轻量,性能开销小,通信高效。
  • 跨平台性:WebSocket可以在不同的操作系统和设备上使用,具有较好的跨平台性。
  • 总的来说,WebSocket是一种高效、稳定的网络通信协议,适用于需要实时交互的Web应用程序。

发展简介

WebSocket的历史背景可以追溯到2008年,当时WebSocket协议首次被提出。自2010年开始,WebSocket得到了浏览器厂商的广泛支持,并逐渐成为Web应用程序中实现实时通信的重要技术。在此之前,虽然已经存在一些实时通信技术,但它们通常需要通过入侵现有的web技术来实现,而这些技术并不是为实时应用而设计的。

在WebSocket出现之前,web是建立在HTTP协议的基础上的,而HTTP协议最初完全是作为一种请求-响应机制设计的。这种机制在早期的web应用中表现良好,因为当时的场景只需要处理一个文本文档和一些额外的资源即可。然而,随着web应用的不断发展,对于实时通信的需求也越来越强烈,WebSocket就是在这样的背景下应运而生的。

WebSocket的出现为Internet通信创造了新的可能性,并为真正的实时通讯打开了大门。它提供了一种持久连接的方式,使得服务器和客户端之间可以保持长时间的通信状态,从而实现了真正的双向通信。同时,WebSocket也具有较好的兼容性和跨平台性,可以在不同的操作系统和设备上使用。

总之,WebSocket的历史背景是在web应用程序对于实时通信的需求不断增长的背景下产生的。它提供了一种高效、稳定的网络通信协议,适用于需要实时交互的Web应用程序。

libwebsockets

libwebsockets是一种用于C语言的轻量级网络库,它提供了为创建WebSocket服务器和客户端而编写的API。使用它可以轻松地实现WebSockets、HTTP(S)/1.1等协议。它旨在成为一个高效、灵活和可移植的解决方案。

在这里插入图片描述

现在由意大利的计算机科学家Salvatore Sanfilippo维护,他也是Redis数据库的创建者。

libwebsockets的优点包括:

  • 轻量级:libwebsockets使用C语言编写,不需要任何附加的库或外部依赖项,非常轻量级。
  • 高效性:libwebsockets旨在提供高效性和低消耗,与其他网络库相比,它的消息处理速度更快,内存开销更小。
  • 可移植性:libwebsockets可以在所有主要平台上运行,包括Windows、Linux、Mac OS X等,提供了适用于多个平台的API,且易于移植到其他平台。
  • 支持ws://wss://协议:libwebsockets支持ws://wss://协议,可以选择和OpenSSLCyaSSL或者WolfSSL链接。
  • 事件循环、零拷贝:libwebsockets支持事件循环、零拷贝等功能。
  • API丰富:libwebsockets提供的API相当底层,可以实现简单的功能,对于复杂功能也提供了丰富的API支持。
  • 总之,libwebsockets具有轻量级、高效性、可移植性、支持多种协议、事件循环和零拷贝等特点,是一个功能强大的网络库。

入门示例

这个示例程序创建了一个WebSocket服务器,监听端口号为8000。它使用自定义的协议echo-protocol,当接收到客户端发送的消息时,会将收到的消息原样返回。程序使用lws_create_context创建WebSocket服务器上下文,并使用lws_service处理WebSocket连接。最后,使用lws_context_destroy销毁WebSocket服务器上下文。

#include <libwebsockets.h>  
#include <string.h>  
static int callback_echo(struct lws *wsi, enum lws_callback_reasons reason,  
 void *user, void *in, size_t len) {
	switch (reason) {
		case LWS_CALLBACK_ESTABLISHED: // 当新的连接建立时触发  
		lws_callback_on_writable(wsi);
		break;
		case LWS_CALLBACK_RECEIVE: // 当接收到客户端发送的消息时触发  
		// 直接将收到的消息返回给客户端  
		lws_write(wsi, in, len, LWS_WRITE_TEXT);
		break;
		default:  
		 break;
	}
	return 0;
}
static struct lws_protocols protocols[] = { {
		"echo-protocol",  
		 callback_echo,  
		 0,  
		 128,
	}
	, {
		NULL, NULL, 0, 0
	}
	// 结束标记
}
;
int main(void) {
	struct lws_context_creation_info info;
	memset(&info, 0, sizeof info);
	info.port = 8000;
	// 服务端监听的端口号  
	info.protocols = protocols;
	// 使用自定义的协议  
	info.gid = -1;
	// 不使用组ID  
	info.uid = -1;
	// 不使用用户ID  
	info.options = LWS_SERVER_OPTION_HTTP_HEADERS;
	// 设置选项,允许HTTP头部字段存在消息中  
	struct lws_context *context = lws_create_context(&info);
	// 创建WebSocket服务器上下文  
	while (1) {
		// 循环运行服务器,直到手动停止  
		lws_service(context, 50);
		// 处理WebSocket连接,超时时间设置为50毫秒
	}
	lws_context_destroy(context);
	// 销毁WebSocket服务器上下文  
	return 0;
}

与libuv集成

关键点是libuv的异步I/O机制中调用libwebsockets提供的方法。示例程序如下:

#include <uv.h>  
#include <libwebsockets.h>  
  
static void on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {  
    struct lws *wsi = (struct lws *)stream->data;  
    int n;  
  
    if (nread < 0) {  
        lws_close(wsi, LWS_CLOSE_STATUS_GOINGAWAY, "UV read error");  
        return;  
    }  
  
    if (nread == 0)  
        return;  
  
    n = lws_write(wsi, buf->base, nread, LWS_WRITE_TEXT);  
    if (n < 0) {  
        lws_close(wsi, LWS_CLOSE_STATUS_GOINGAWAY, "Cannot write");  
        return;  
    }  
}  
  
static void on_write(uv_write_t *req, int status) {  
    struct lws *wsi = (struct lws *)req->data;  
    if (status) {  
        lws_close(wsi, LWS_CLOSE_STATUS_GOINGAWAY, "UV write error");  
        return;  
    }  
}  
  
static void service(struct lws *wsi) {  
    uv_loop(uv_default_loop()); // 开始事件循环  
}  
  
static int callback(struct lws *wsi, enum lws_callback_reasons reason) {  
    switch (reason) {  
        case LWS_CALLBACK_ESTABLISHED: // 当新的连接建立时触发  
            uv_write_t *req = (uv_write_t *)malloc(sizeof(*req)); // 创建UV写入请求对象  
            uv_buf_t buf = uv_buf_init((char *)"Hello, client!", 13); // 创建缓冲区对象,存储要写入的消息内容  
            uv_write(req, (uv_stream_t *)&wsi->stream, &buf, 1, NULL); // 向客户端写入消息,并关联回调函数on_write和请求对象req  
            req->data = wsi; // 将请求对象关联到WebSocket连接对象wsi上,方便后续处理请求时获取wsi对象  
            break;  
        case LWS_CALLBACK_RECEIVE: // 当接收到客户端发送的消息时触发  
            // 处理接收到的消息,这里只是简单地打印消息内容到控制台  
            printf("Received message: %s\n", (char *)in);  
            break;  
        default: // 其他情况处理,例如连接关闭等操作可以在这里处理  
            break;  
    }  
    return 0; // 返回0表示处理成功,否则表示处理失败,会触发回调函数on_close或on_error等操作  
}
作者:岬淢箫声
日期:2023年11月7日
版本:1.0
链接:http://caowei.blog.csdn.net

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1180320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将json数据转换为Python字典

import requests from bs4 import BeautifulSoup import json# 定义代理信息 proxy_host www.duoip.cn proxy_port 8000# 定义要爬取的url url http://localhost:9200/_search# 创建一个requests.Session对象&#xff0c;并设置代理 session requests.Session() session.pr…

Python3,3行代码,给照片填充背景色,从此跟照相馆说拜拜。

3行代码照片上背景色 1、引言2、代码实战2.1 思路2.2 安装2.3 实例 3、总结 1、引言 小屌丝&#xff1a; 鱼哥&#xff0c;帮个忙。 小鱼&#xff1a; 在开车。 小屌丝&#xff1a;… 那你先忙&#xff0c;不打扰你了。 小鱼&#xff1a;…我可以说话的&#xff0c;没事。 小屌…

3.4、Linux小程序:进度条

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 回车与换行的概念和区别 行缓冲区概念 进度条代码 version1 version2 version3 回车与换行的概念和区别 换行\n&#xff0c;回车\r 似乎无需多言 行缓冲区概念 这里我们通过例子来简单理解即可&#xff0c;深入…

Wait-Notify机制

文章目录 1. 简介2. 相关API3. wait notify的正确姿势4. 总结 1. 简介 回顾Minitor锁的结构&#xff1a; Owner线程发现条件不满足&#xff0c;调用wait方法&#xff0c;即可进入WaitSet变为WAITING状态BLOCKED和WAITING的线程都处于阻塞状态&#xff0c;不占用CPU时间BLOCK…

新浪微博一键删除所有内容

亲自测试用 具体操作如下&#xff1a; 对应的 1 2 如下&#xff0c;进入这个界面是按F12 就可以看到 最后画横线的位置 替换自己的id 对应的就是 3 具体代码如下 //向删除接口发起请求&#xff0c;删除对应节点 function del_weibo(id) {var myHeaders new Headers();myHea…

小白学爬虫:通过商品ID获取1688跨境属性数据接口|1688商品属性接口|1688一件代发数据接口|1688商品详情接口

通过商品ID获取1688跨境属性数据接口可以使用1688开放平台提供的API接口实现。以下是获取跨境属性数据的基本步骤&#xff1a; 点击获取测试key和secret构造请求参数&#xff0c;包括商品ID和其他必要参数&#xff0c;如接口权限、请求类型等。通过API接口链接&#xff0c;将请…

App启动——Application的创建

Application的创建 一个 app 启动时候创建一个 Application 对象。这个对象的创建时间在 frameworks 中调用创建的&#xff0c;创建流程可见下图&#xff0c;涉及的几个主要的类调用。 一、主线程运行入口 ​ APP进程起来后&#xff0c;主线程运行入库 ActivityThread.main()…

Docker DeskTop的安装(Windows版本)

目录 一、官网下载Docker安装包 二、安装Docker DeskTop 2.1 双击 Docker Installer.exe 以运行安装程序 2.2 安装操作 2.3 关于更改Docker安装位置 2.3.1 自定义安装路径&#xff08;不推荐&#xff09; 2.3.2 移动 Docker 镜像存储位置 三、启动Docker DeskTop 一、官…

GaussDB SQL基础语法-变量常量

目录 一、前言 二、GaussDB数据库中的常量和变量的基本概述及语法定义 1、变量定义 2、常量定义 3、其他&#xff08;%TYPE、%ROWTYPE属性&#xff09; 三、在GaussDB数据库中如何使用变量&常量&#xff08;示例&#xff09; 示例一&#xff0c;定义常量&变量&a…

有什么软件可以管控员工的电脑桌面

信息化的快速发展&#xff0c;员工在工作中使用电脑的情况越来越普遍。然而&#xff0c;员工在使用电脑时可能会出现工作效率低下、滥用公司资源等问题&#xff0c;因此对员工电脑进行监测和管理显得尤为重要。 1、域之盾软件 它是一款功能强大的电脑监控软件&#xff0c;可以…

(二)Spring源码解析:默认标签解析

一、概述 还记得我们在上一讲末尾提到的关于默认标签解析和自定义标签解析吧。本讲就来针对默认标签解析进行讲解。为了便于衔接上一讲的内容&#xff0c;我们将源码部分粘贴出来&#xff1a; 从上图中的源码中&#xff0c;我们可以看出默认标签的解析是在parseDefaultElement…

Unit2_1:动态规划DP

文章目录 一、介绍二、0-1背包问题问题描述分析伪代码时间复杂度 三、钢条切割问题问题描述分析伪代码过程 四、矩阵链乘法背景性质分析案例伪代码 一、介绍 动态规划类似于分治法,它们都将一个问题划分为更小的子问题 最优子结构:问题的最优解包含子问题的最优解。DP适用的原…

一种单总线串口通信的调试方法

单总线的优点&#xff1a; 节省IO口&#xff0c;发送时可以将单片机的RXD设置为普通IO进行软件模拟发送&#xff0c;发送完设置为串口接收。避免通信干扰&#xff0c;由于是通过IO口对三极管/MOS管进行拉高拉低&#xff0c;外部信号不易对IO口进行干扰&#xff0c;EMI&#xf…

代码随想录算法训练营第四十六天 | LeetCode 139. 单词拆分、多重背包、背包总结

代码随想录算法训练营第四十六天 | LeetCode 139. 单词拆分、多重背包、背包总结 文章链接&#xff1a;单词拆分 多重背包 背包总结 视频链接&#xff1a;单词拆分 1. LeetCode 139. 单词拆分 1.1 思路 本题的那些单词就是物品&#xff0c;字符串就是背包&#xff0c;问用这些…

大数据学习之一文学会Spark【Spark知识点总结】

文章目录 什么是SparkSpark的特点Spark vs HadoopSparkHadoopSpark集群安装部署Spark集群安装部署StandaloneON YARN Spark的工作原理什么是RDDRDD的特点Spark架构相关进程Spark架构原理 Spark实战&#xff1a;单词统计Scala代码开发java代码开发任务提交 Transformation与Acti…

echarts 类目轴设置xAxis.interval不起效果

情景&#xff1a;在xAxis.typecategory&#xff1b;设置xAxis.interval不起效果&#xff1b; 解决方案&#xff1a;通过设置xAxis.axisLabel.interval属性

【H616_语言小美_控制安卓刷抖音项目 orangePi zero2 (已开源) 】.md uptada:23/11/07

文章目录 H616_语言小美_控制安卓刷抖音项目小美效果展示H616 ubuntu系统 安装adb智能公元 SU-03T 离线语音模组 固件制作配合串口实现 小美_控制安卓刷抖音 H616_语言小美_控制安卓刷抖音项目 注意&#xff1a;orangePi zero2 H616 安装系统为ubuntu 小美效果展示 语言小美 …

企业级私有化部署数字办公工具集合,解决企业全方位需求,快收藏

随着信息技术的日新月异&#xff0c;企业对IT建设的依赖程度越来越高。为了满足这一需求&#xff0c;软开企服凭借积累了多年的项目经验&#xff0c;推出了一款名为JVS的私有化部署企业信息化底座。JVS涵盖了多个产品领域&#xff0c;如协同办公、低代码开发、数据分析、风控决…

KaiOS APN配置文件apn.json调试验证方法(无需项目全编)

1、KaiOS 的应用就类似web应用&#xff0c;结合文件夹路径webapp字面意思理解。 2、KaiOS APN配置文件源代码在apn.json&#xff0c; &#xff08;1&#xff09;apn.json可以自定义路径&#xff0c;通过配置脚本实现拷贝APN在编译时动态选择路径在机器中生效。 &#xff08;…

linux复习笔记03(小滴课堂)

find命令&#xff1a; d查找目录&#xff1a; 按照文件权限查找&#xff1a; 600全部权限&#xff1a; -user根据所属主&#xff1a; 上面的例子是找出文件并打印有多少行。 我们也可以把我们查询到的结果复制到其它文件位置中去&#xff1a; 复制成功。 -mtime根据修改时间…