当前位置: 首页 > 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>数…...

咱们今天聊点硬核但有趣的东西——用纳米级乐高积木(二氧化钛超表面)玩转光漩涡。想象一下,你手上有把能操控光波前形状的万能钥匙,这就是超表面的魅力所在

FDTD模型:基于超表面的完美涡旋光案例。 宽带任意阶 完美涡旋光束 介绍&#xff1a;全介质超表面实现完美矢量涡旋光束生成和完美庞加莱球生成&#xff0c;完美矢量涡旋光束不随拓扑荷的变化而变化&#xff0c;同时满足矢量光场的偏振变化&#xff0c;主要用于光学加密等领域&a…...

R16增强型Type II码本:空频域联合压缩与量化反馈机制解析

1. R16增强型Type II码本的技术背景 在5G Massive MIMO系统中&#xff0c;信道状态信息&#xff08;CSI&#xff09;反馈的精度和效率直接影响着系统性能。R15 Type II码本虽然已经实现了空域压缩&#xff0c;但随着频段向毫米波延伸和天线规模扩大&#xff0c;传统方案面临反馈…...

【中文文献管理效率提升90%】茉莉花插件:科研工作者的智能文献处理解决方案

【中文文献管理效率提升90%】茉莉花插件&#xff1a;科研工作者的智能文献处理解决方案 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件&#xff0c;用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum…...

亿级并发下的抢票系统架构:从DDD到微服务的实战解析

1. 抢票系统的业务挑战与技术痛点 每年春运期间&#xff0c;12306系统都要面对全球最严苛的高并发考验。2019年春运最高峰日点击量达到1495亿次&#xff0c;相当于每个中国人当天点击了100多次。这种量级的并发请求&#xff0c;如果直接打到数据库上&#xff0c;就算是把阿里云…...

革新性图表创作:Mermaid Live Editor如何重构技术可视化工作流

革新性图表创作&#xff1a;Mermaid Live Editor如何重构技术可视化工作流 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-liv…...

Pixel Script Temple 为C++高性能计算项目生成优化脚本

Pixel Script Temple 为C高性能计算项目生成优化脚本 1. 高性能计算开发的痛点 在C高性能计算领域&#xff0c;开发者经常面临一个共同困境&#xff1a;明明硬件资源充足&#xff0c;但程序性能就是上不去。你可能也遇到过这样的情况 - 代码逻辑没问题&#xff0c;算法也正确…...

别再手动点灯了!用Simulink串口实时控制STM32,5分钟搞定双向通信

基于Simulink与STM32的实时双向通信实战指南 在嵌入式系统开发中&#xff0c;快速原型验证是提升效率的关键环节。传统开发模式下&#xff0c;工程师需要花费大量时间编写底层通信协议、调试硬件接口&#xff0c;而真正核心的控制算法验证反而被边缘化。本文将介绍一种高效开发…...

MTK手机屏显干扰全解析:亮灭屏、射频干扰与TP失灵,我是如何用PLL_CLOCK和Porch参数解决的

MTK手机屏显干扰全解析&#xff1a;亮灭屏、射频干扰与TP失灵实战解决方案 引言&#xff1a;当屏幕开始"跳舞"——移动设备显示异常背后的复杂世界 那块6.5英寸的OLED屏幕又一次在通话过程中突然闪烁起来&#xff0c;像被无形的幽灵操控着。作为MTK平台驱动开发工程师…...

【实战】从理论到代码:用Python实现相位一致性特征提取

1. 相位一致性特征提取的核心原理 相位一致性&#xff08;Phase Congruency&#xff09;是计算机视觉领域一种强大的特征提取方法&#xff0c;它从根本上改变了传统边缘检测的思路。我第一次接触这个概念是在处理一组光照条件差异很大的工业检测图像时&#xff0c;当时用Sobel和…...

PyTorch 2.8镜像实战案例:内容创作团队基于Diffusers批量生成社媒短视频

PyTorch 2.8镜像实战案例&#xff1a;内容创作团队基于Diffusers批量生成社媒短视频 1. 项目背景与需求 在当今社交媒体内容爆炸式增长的时代&#xff0c;短视频创作团队面临着巨大的内容生产压力。传统视频制作流程需要经历脚本创作、拍摄、剪辑等多个环节&#xff0c;一个专…...