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

实习日志30

概要

高拍仪硬件通信原理,WebSocket源码解析(JavaScript)

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

ps:本来想写sm4加密和解密算法的,但是sm3一个加密都看的我头昏昏的,就先不为难自己了,说说WebSocket的源码解析吧

源自: HTML5 WebSocket | 菜鸟教程 (runoob.com)

整体架构流程

拟人化展示从HTTP协议升级到WebSocket协议的过程:

1、发送一个GET请求
关键: Upgrade: websocket; Connection: Upgrade;
这两个就告诉服务器,我要发起websocket协议,我不是HTTP。

2、服务器收到了协议,返回一个 Switching Protocol, 这样就连接成功了。

3、接下来的通信都是websocket, 这样就很好的连接了。

源自:WebSocket建立连接的过程_websocket如何建立连接-CSDN博客

 

技术名词解释

连接请求:Connection: Upgrade;

通信消息数据:(二进制消息)

技术细节

一、建立连接:

在高拍仪初始化时建立连接

初始化,设置显示相机屏幕大小,设置自动裁剪(初始化后才能设置)

function LoadCameraDocument() {if (!window.WebSocket) {alert("浏览器不支持HTML5,请更新浏览器或者使用其它浏览器");}//console.log("LoadCameraDocument");var obj = document.getElementById("CameraCtl");Cam_ControlInit(obj, 0, 0, 600, 400);// 模拟异步硬件初始化setTimeout(function () {// 设置自动裁剪SetCameraCutMode();}, 2500); // 假设2.5秒后硬件初始化完成// 模拟异步硬件初始化setTimeout(function () {// 设置自动裁剪SetCameraCutMode();}, 5000); // 完不成再来一下
}

 连接WebSocket,初始化相机

//*************摄像头操作初始化***************
function Cam_ControlInit(documentObj, mX, mY, mwidth, mheight) {WebSocketConnect();InitCanvas(documentObj, mX, mY, mwidth, mheight);//console.log("Cam_ControlInit");
}

 设置连接地址和开启时函数,

        设置心跳检测、断线重连、获取设备数目

        完成后输出连接成功 "socket.onopen"

socket = new WebSocket("ws://127.0.0.1:22225");
socket.binaryType = "arraybuffer";socket.onopen = function (event) {//heartCheck.reset().start(); heartCheck();isSocketConnect = true;clearInterval(intervalId);//if (isOpenMainCamera == false)         Cam_GetDevCount();console.log("socket.onopen");};

二、发送数据:

首先要有心跳,if (isSocketConnect)

其次,创建二进制数组 var aDataArray = new Uint8Array(totalLen)

然后,消息分装

最后,发送二进制消息 socket.send(aDataArray.buffer);

示例“处理拍照逻辑发送消息逻辑”代码:


function CaptureImage(fileAddr) {if (isSocketConnect) {// var pathArray = stringToUint8Array(fileAddr);if (fileAddr == "") {var packageCount = 1;var len = 0;var pindex = 0;var totalLen = 12;var aDataArray = new Uint8Array(totalLen);aDataArray[0] = 0x77;aDataArray[1] = 0x88;aDataArray[2] = 0x10;aDataArray[3] = 0x00;aDataArray[4] = len >> 16 & 0xff;aDataArray[5] = len >> 8 & 0xff;aDataArray[6] = len & 0xff;aDataArray[7] = packageCount >> 8 & 0xff;   //包总数aDataArray[8] = packageCount & 0xff;   //包总数aDataArray[9] = 0;   //分包长度aDataArray[10] = pindex >> 8 & 0xff;   //包序号aDataArray[11] = pindex & 0xff;    //包序号console.log("pindex:" + pindex);socket.send(aDataArray.buffer);} else {var path = encodeURI(fileAddr);//console.log(path);var pathArray = stringToByte(path);var len = pathArray.length;var packageCount = 0;var tmpLen = len;while (tmpLen > 0) {tmpLen = tmpLen - 90;packageCount++;}console.log("packageCount:" + packageCount);var pindex = 0;tmpLen = len;while (tmpLen > 0) {tmpLen = tmpLen - 90;if (tmpLen > 0) {var totalLen = 90 + 12;var aDataArray = new Uint8Array(totalLen);aDataArray[0] = 0x77;aDataArray[1] = 0x88;aDataArray[2] = 0x10;aDataArray[3] = 0x00;aDataArray[4] = len >> 16 & 0xff;aDataArray[5] = len >> 8 & 0xff;aDataArray[6] = len & 0xff;aDataArray[7] = packageCount >> 8 & 0xff;   //包总数aDataArray[8] = packageCount & 0xff;   //包总数aDataArray[9] = 90;   //分包长度aDataArray[10] = pindex >> 8 & 0xff;   //包序号aDataArray[11] = pindex & 0xff;    //包序号console.log("pindex:" + pindex);for (var i = 0; i < 90; i++) {aDataArray[12 + i] = pathArray[i + pindex * 90];}socket.send(aDataArray.buffer);} else {var totalLen = 90 + tmpLen + 12;  // 此时tmpLen为负数,做加法运算var aDataArray = new Uint8Array(totalLen);aDataArray[0] = 0x77;aDataArray[1] = 0x88;aDataArray[2] = 0x10;aDataArray[3] = 0x00;aDataArray[4] = len >> 16 & 0xff;aDataArray[5] = len >> 8 & 0xff;aDataArray[6] = len & 0xff;aDataArray[7] = packageCount >> 8 & 0xff;   //包总数aDataArray[8] = packageCount & 0xff;   //包总数aDataArray[9] = 90 + tmpLen;   //分包长度aDataArray[10] = pindex >> 8 & 0xff;   //包序号aDataArray[11] = pindex & 0xff;    //包序号console.log("pindex:" + pindex);for (var i = 0; i < (90 + tmpLen); i++) {aDataArray[12 + i] = pathArray[i + pindex * 90];}socket.send(aDataArray.buffer);}pindex++;toSleep(80);}}}
}

三、响应数据:

例如:拍照时数据处理

创建onmessage方法,心跳检测必写

socket.onmessage = function (event) {// heartCheck.reset().start();      var rDataArr = new Uint8Array(event.data);if (rDataArr.length > 0) {// WebSocket心跳检测if (rDataArr[0] == 0x11 && rDataArr[1] == 0x11 && rDataArr[2] == 0x11) {console.log("socket心跳 ❤");}// 处理rDataArr数据// 省略...示例代码}}

响应数据方法:socket.onmessage = function (event) {}

示例"处理拍照结果返回响应逻辑"代码:

//拍照结果返回
if (rDataArr[2] == 0x10) {var flag;if (rDataArr[3] == 0x01) {flag = 0;var imgpathLen = rDataArr[4] * 256 + rDataArr[5];if (imgpathLen == 0) {var base64Len = rDataArr[6] * 65536 + rDataArr[7] * 256 + rDataArr[8];var imgPathStr = "";var base64Data = new Uint8Array(base64Len);for (var i = 0; i < base64Len; i++) {base64Data[i] = rDataArr[9 + imgpathLen + i];}var base64Str = Uint8ArrayToString(base64Data);GetCaptrueImgResultCB(flag, imgPathStr, base64Str);} else {var base64Len = rDataArr[6] * 65536 + rDataArr[7] * 256 + rDataArr[8];var pData = new Uint8Array(imgpathLen);for (var i = 0; i < imgpathLen; i++) {pData[i] = rDataArr[9 + i];}var str = byteToString(pData);var imgPathStr = decodeURIComponent(str);var base64Data = new Uint8Array(base64Len);for (var i = 0; i < base64Len; i++) {base64Data[i] = rDataArr[9 + imgpathLen + i];}var base64Str = Uint8ArrayToString(base64Data);GetCaptrueImgResultCB(flag, imgPathStr, base64Str);}}if (rDataArr[3] == 0x02) {flag = 2;GetCaptrueImgResultCB(flag, "", "");}}

小结

WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,通过它可以实现实时的数据传输。建立WebSocket连接的过程包括发送一个GET请求并指定协议升级,服务器返回一个Switching Protocol响应,连接成功后即可进行WebSocket通信。在实际应用中,可以通过WebSocket发送和接收二进制消息来实现各种功能,例如拍照、传输文件等。需要注意的是,为了保持连接的稳定性,通常会实现心跳检测和断线重连功能。

  1. 深入理解WebSocket协议:通过实际编码,我更深入地理解了WebSocket协议的工作原理和建立连接的过程。

  2. 网络通信能力提升:通过处理WebSocket通信的逻辑,我提升了自己的网络通信能力,包括发送和接收数据的处理能力。

  3. 异步编程理解:WebSocket通信通常是异步的,我巩固了如何处理异步通信,例如通过回调函数处理接收到的消息。

  4. 实践经验:通过实际编写WebSocket通信相关的代码,我积累了宝贵的实践经验,可以帮助我更好地理解和应用相关知识。

  5. 问题解决能力:在编写过程中可能遇到了各种问题,通过解决这些问题,我提升了自己的问题解决能力和调试技巧。

相关文章:

实习日志30

概要 高拍仪硬件通信原理&#xff0c;WebSocket源码解析&#xff08;JavaScript&#xff09; WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据…...

【MySQL】探索表结构、数据类型和基本操作

表、记录、字段 数据库的E-R&#xff08;entity-relationship&#xff0c;实体-关系&#xff09;模型中有三个主要概念&#xff1a; 实体集 、 属性 、 关系集 。 一个实体集对应于数据库中的一个表&#xff0c;一个实体则对应于数据库表 中的一行&#xff0c;也称为一条记录。…...

解决采集时使用selenium被屏蔽的办法

解决采集时使用selenium被屏蔽的办法 实用seleniumbase uc模式 from seleniumbase import Driver driver Driver(ucTrue) # 使用UC模式UC模式是基于undetected-chromedriver 但做了一些优化更新&#xff0c;使用起来更方便 官方例子&#xff1a; from seleniumbase import …...

stream流-> 判定 + 过滤 + 收集

List<HotArticleVo> hotArticleVos hotArticleVoList .stream() .filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList()); 使用Java 8中的Stream API对一个名为hotArticleVoList的列表进行过滤操作&#xff0c;筛选出符合指定条件…...

人工智能在测绘行业的应用与挑战

目录 一、背景 二、AI在测绘行业的应用方向 1. 自动化特征提取 2. 数据处理与分析 3. 无人机测绘 4. 智能导航与路径规划 5. 三维建模与可视化 6. 地理信息系统&#xff08;GIS&#xff09;智能化 三、发展前景 1. 技术融合 2. 精准测绘 3. 智慧城市建设 4. 可…...

四、分类算法 - 随机森林

目录 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结 sklearn转换器和估算器KNN算法模型选择和调优朴素贝叶斯算法决策树随机森林 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结...

pytorch -- DataLoader

定义 提供了给定数据集的迭代器 torch.utils.data.DataLoader(dataset, batch_size1, 每次拿多少数据 shuffleNone, 是否打乱 samplerNone, batch_samplerNone, num_workers0, 多进程&#xff08;加载数据时采用&#xff09;默认是0,使用主进程加载数据 collate_fnNone, p…...

【MySQL面试复习】索引创建的原则有哪些?

系列文章目录 在MySQL中&#xff0c;如何定位慢查询&#xff1f; 发现了某个SQL语句执行很慢&#xff0c;如何进行分析&#xff1f; 了解过索引吗&#xff1f;(索引的底层原理)/B 树和B树的区别是什么&#xff1f; 什么是聚簇索引&#xff08;聚集索引&#xff09;和非聚簇索引…...

四种主流的prompt框架

省流版&#xff1a; 文章介绍了在使用GPT时的四种prompt框架&#xff0c;有利于使用者打磨提问风格&#xff0c;与GPT进行更好的交互以提高生产力&#xff0c;能帮助大家有效提高工作效率~ 创作不易&#xff0c;如果对你有帮助的话&#xff0c;还请三连支持~ 想要使用Prompt…...

Educational Codeforces Round 160 (Rated for Div. 2) E. Matrix Problem(费用流)

原题链接&#xff1a;E. Matrix Problem 题目大意&#xff1a; 给出一个 n n n 行 m m m 列的 0 / 1 0/1 0/1 矩阵&#xff0c;再给出一些限制条件&#xff1a;一个长为 n n n 的数组 a a a&#xff0c;和一个长为 m m m 的数组 b b b 。 其中 a i a_{i} ai​ 表示第 …...

基于SpringBoot的气象数据监测分析大屏

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…...

关于硅的制造芯片的过程

芯片是如何制作的&#xff1f; 先将硅融化制成硅晶片&#xff0c;再用光刻机印压电路。 bilibili芯片制作视频 硅晶片作为现代芯片的主要元件&#xff0c;广泛用于集成电路。 首先将多晶硅放入特制的密封炉&#xff0c;排除其中空气后加热到1420摄氏度&#xff0c;将融化的硅放…...

【深度学习笔记】3_10 多层感知机的PyTorch实现

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.10 多层感知机的简洁实现 下面我们使用PyTorch来实现上一节中的多层感知机。首先导入所需的包或模块。 import torch from torch import nn from torch.nn import …...

输入法在 Android13上候选词 候选区域 不显示的问题

背景 自研的输入法发现在 Android13 平台上不显示候选区域&#xff0c;在之前平台上以及需求是输入英文时不显示&#xff0c;中文需要显示。 最终解决办法&#xff1a;setExtractViewShown(false) Override public View onCreateCandidatesView() {...setExtractViewShown(f…...

Java 面向对象进阶 18 JDK8、9开始新增的方法;接口的应用;适配器设计模式;内部类(黑马)

一、JDK8开始新增的方法 默认方法不是抽象方法&#xff0c;所以不强制被重写&#xff1a; 但是如果被重写&#xff0c;就要去掉default关键字&#xff1a; public可以省略&#xff0c;但是default不可以省略&#xff1a; public是灰色的&#xff0c;代表可以省略 但是default是…...

数据结构-二分搜索树(Binary Search Tree)

一,简单了解二分搜索树 树结构: 问题:为什么要创造这种数据结构 1,树结构本身是一种天然的组织结构,就好像我们的文件夹一样,一层一层的. 2,树结构可以更高效的处理问题 二,二分搜索树的基础 1、二叉树 2,二叉树的重要特性 满二叉树 总结: 1. 叶子结点出现在二叉树的最…...

YOLO如何训练自己的模型

目录 步骤 一、打标签 二、数据集 三、跑train代码出模型 四、跑detect代码出结果 五、详细操作 步骤 一、打标签 &#xff08;1&#xff09;在终端 pip install labelimg &#xff08;2&#xff09;在终端输入labelimg打开 如何打标签&#xff1a; 推荐文章&#xf…...

05 EXTI外部中断

一、中断系统 中断系统&#xff1a;管理和执行中断的逻辑结构。中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件——中断源&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继…...

2024.2.23

1.1.1 信号默认、捕获、忽略处理(普通信号) #include <myhead.h> void handler(int signo) {if(signoSIGINT){printf("用户键入 ctrlc\n");} } int main(int argc, const char *argv[]) {//忽略信号if(signal(SIGINT,SIG_IGN)SIG_ERR){perror("signal er…...

PHP实现分离金额和其他内容便于统计计算

得到的结果可以粘贴到excel计算 <?php if($_GET["x"] "cha"){ $tips isset($_POST[tips]) ? $_POST[tips] : ; $pattern /(\d\.\d|\d)/; $result preg_replace($pattern, "\t\${1}\t", $tips); echo "<h2><strong>数…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...