实习日志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. 问题解决能力:在编写过程中可能遇到了各种问题,通过解决这些问题,我提升了自己的问题解决能力和调试技巧。

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

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

相关文章

【数据库的介绍、分类、作用和特点】的讲解

数据库的介绍、分类、作用和特点 1. 数据库2. 介绍3. 分类3.1 按数据模型分类3.2 按用户数量分类3.3 按数据分布分类 4. 作用5. 特点5.1 特定类型的数据库特点 1. 数据库 数据库是用于存储、管理、处理和检索数据的系统&#xff0c;以下是基于不同维度的数据库的介绍、分类、作…

java RMI(远程方法调用)

java RMI(Remote Method Invocation)远程方法调用。为什么称为远程方法调用呢&#xff1f;因为是两个JVM间进行通讯。两个JVM一个作为服务提供端&#xff0c;另一个作为服务调用端。 首先需要定义一个远程调用的接口&#xff0c;这个接口要继承Remote接口。并且远程接口方法要…

DWT硬件延时

DWT硬件延时 文章目录 DWT硬件延时软件&硬件延时方案软件延时硬件延时方案 DWT硬件延时方案DWT硬件延时方案DEMCR寄存器DWT硬件延时方案实现延时初始化&#xff1a;US延时&#xff1a;MS延时&#xff1a; 软件&硬件延时方案 软件延时 static void Delay(uint32_t cou…

Leetcode刷题笔记题解(C++):6. Z 字形变换

思路&#xff1a;遍历时候需要更新步进长度 到达0行的时候步进长度为1&#xff1b;到达最后一行numRows-1行的时候步进长度为-1&#xff1b;代码如下所示&#xff1a; class Solution { public:string convert(string s, int numRows) {//如果字符串长度为1或者所给行数为1 …

vscode更新至1.86版本后,ssh远程连接服务器出现异常

问题 you are connected to an OS version that is unsupported by Visual Studio Code 你已连接到不受Visual Studio Code支持的OS 版本 原因是vscode更新到1.86版本后要求远程连接服务器的内核版本和库版本需要符合下面条件。 解决方法 因此有两种方法解决 1.更新服务器…

[数据集][目标检测]课堂行为数据集VOC+YOLO格式671张6类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;671 标注数量(xml文件个数)&#xff1a;671 标注数量(txt文件个数)&#xff1a;671 标注类别…

开源MBG----renrenGenerator

目录 1.克隆项目到本地 2.编辑数据库连接 3.定义生成的代码模版 4.验证生成结果 5.多说一句 项目简介&#xff1a;人人开源项目的代码生成器&#xff0c;可在线生成entity、xml、dao、service、vue、sql代码&#xff0c;减少70%以上的开发任务。 项目地址&#xff1a;ren…

Floor报错原理详解+sql唯一约束性

目录 floor报错原理 唯一性约束 主键约束&#xff1a; 创建约束的形式 删除约束 删除唯一性约束&#xff08;UNIQUE Constraint&#xff09; 在SQL Server中&#xff1a; 在MySQL中&#xff1a; 在PostgreSQL中&#xff1a; 删除主键约束&#xff1a; floor报错原理 …

免费SSL证书申请流程及地址

1&#xff0c;选择证书提供商&#xff1a;有许多机构提供免费的SSL证书&#xff0c;如JoySSL。选择一个可靠的提供商是第一步。 免费SSL证书申请地址https://www.joyssl.com/certificate/select/free.html?nid5 2&#xff0c;验证域名&#xff1a;根据提供商的要求&#xff…

力扣4题:寻找两个正序数组的中位数

【题目描述】 &#xff08;困难&#xff09;给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平…

sql实战_基于某推荐比值问题

将一个月内某PL对应的MBLX出现的最高的频次的占比值最大的值统计出来&#xff0c;并且还要把XHLX&#xff0c;MBLX字段添加上作为最终的推荐字段 Select * from(select *,row_number( ) over (partition by PL order by 占比最大值 desc ) rn from 表) where rn 1&#xff1b…

TensorRT及CUDA自学笔记003 NVCC及其命令行参数

TensorRT及CUDA自学笔记003 NVCC及其命令行参数 各位大佬&#xff0c;这是我的自学笔记&#xff0c;如有错误请指正&#xff0c;也欢迎在评论区学习交流&#xff0c;谢谢&#xff01; NVCC是一种编译器&#xff0c;基于一些命令行参数可以将使用PTX或C语言编写的代码编译成可…

H5多用途的产品介绍展示单页HTML5静态网页模板

H5多用途的产品介绍展示单页HTML5静态网页模板 源码介绍&#xff1a;一款H5自适应多用途的产品介绍展示单页HTML静态网页模板&#xff0c;可用于团队官网、产品官网。 下载地址&#xff1a; https://www.changyouzuhao.cn/13534.html

24-树-完全二叉树的节点个数

这是树的第24篇算法&#xff0c;力扣链接。 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面一层…

Selenium自动化测试:提升效果的关键技巧

在软件开发过程中&#xff0c;自动化测试是提高效率和质量的重要手段。而Selenium作为一个广泛使用的自动化测试工具&#xff0c;为开发者提供了强大的功能和灵活性。本文将介绍Selenium的概念&#xff0c;并分享一些提升自动化测试效果的关键技巧。 什么是Selenium&#xff1…

HarmonyOS应用开发者基础认证 模拟考试 题库

模拟考试 1.在Colum和Row容器组件中&#xff0c;justifycontent用于设置子组件在主轴方向上的对齐格式&#xff0c;alignItems用于设置子组件在交叉抽方向上的对齐格式。 正确(True) 2.Video组件可以支持本地视频路径和网络路径播放。播放网络视频时&#xff0c;需要申请权限oh…

Intel SGX 概述

文章目录 前言一、SGX介绍1.1 指令介绍1.2 数据结构 二、内存保护过程2.1 enclave页面缓存&#xff08;EPC&#xff09;2.2 Enclave页面缓存映射&#xff08;EPCM&#xff09; 参考资料 前言 SGX是Intel开发的新的处理器技术&#xff0c;可以在计算平台上提供一个可信的空间&a…

AI智能分析网关V4智慧工厂视频智能监管与风险预警平台建设方案

一、背景需求分析 1&#xff09;随着信息技术的迅猛发展和制造业竞争的加剧&#xff0c;智慧工厂成为了推动制造业转型升级的重要引擎。智慧工厂解决方案通过整合物联网、人工智能、大数据分析等先进技术&#xff0c;实现生产过程的智能化、自动化和高效化&#xff0c;为企业提…

python 基础知识点(蓝桥杯python科目个人复习计划52)

今日复习内容&#xff1a;还是做题 例题1&#xff1a;四元组问题 问题描述&#xff1a; 从小学开始&#xff0c;小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期&#xff0c;他遇到了一个非常有趣的问题&#xff0c;那就算给定一个长度为n…

openslide Could not find module ‘libopenslide-0.dll‘

本文仅对与在win操作系统下的用户&#xff0c;在openslide官网中下载对应的二进制文件&#xff0c;然后使用pip安装 pip install openslide-python 解压二进制文件&#xff0c;把bin目录下的所有文件复制粘贴到python环境中就行&#xff0c;例如我使用的环境是anaconda的base…