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

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯(包括后端实现心跳检测)

  • 一级目录
    • 二级目录
      • 三级目录
  • 前言
  • 一、Web Socket 简绍
    • 1 为什么用 websocket?
  • 二、代码实现
    • 1、前端(html)
      • 1.1、无前端向后端发送消息
      • 1.2、有前端向后端发送消息
    • 2、后端具体代码(spring boot)
    • 2.1、maven依赖
    • 2.2、配置类
    • 3、Web Socket连接工具类
    • 2.3、Controller用于测试主动发送消息
    • 2.4、定时任务,用于调用主动向客户端发送心跳
  • 三、测试
    • 1、 测试消息发送
      • 1.1、前端日志
      • 1.2、后端日志
    • 2、测试客户端异常断开,服务器通过心跳检测自动剔除掉异常对话。

一级目录

二级目录

三级目录

前言

写这个项目主要是有有个项目需要后端有数据实话返回前端,一开始采用前端轮询的方式,后面觉得及时性上有些不行,然后改为使用websocket ,具体实现demo以及测试流程发出来提供交流学习,

一、Web Socket 简绍

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

1 为什么用 websocket?

换句话说,websocket 解决了什么问题?答案是,解决了两个主要问题:

  • 只能客户端发送请求
  • 一段时间内的频繁信息发送

假设现在需要设计一个实时预警系统的通知模块,那么作为工程师我们应该怎么设计通知的这个功能呢?因为这些系统的数据来源,一般他通过硬件设备采集到后台的,如果我们现在只有 http 协议,那么我们只能让客户端不断地轮询服务器,轮询的时间间隔越小越能接近实时的效果。可是,轮询的效率低,又浪费资源。针对这样的场景,websocket 应运而生。

在这里插入图片描述
特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易,是一个可靠的传输协议。
(2)与 HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

二、代码实现

1、前端(html)

1.1、无前端向后端发送消息

在这里插入图片描述

uid实际开发中应该使用唯一值作为当前对话的key

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
消息展示区:<br/>
<div id="textArea"></div></body>
<script>var textArea = document.getElementById('textArea');var websocket = null;//如果浏览器支持websocket就建立一个websocket,否则提示浏览器不支持websocket //uid应该要用唯一标识,为了测试方便看if('websocket' in window){websocketPage = new WebSocket('ws://localhost:8080/websocket/' + 99);}else{alert('浏览器不支持websocket!');}//建立websocket时自动调用websocketPage.onopen = function (event) {console.log('建立连接');}//关闭webscoket时自动调用websocketPage.oncolse = function (event){console.log('关闭连接');}//websocket接收到消息时调用websocketPage.onmessage = function (event){//将接收到的消息展示在消息展示区  (心跳响应回来的消息不显示)if (event.data !== "conn_success"){textArea.innerText += event.data;textArea.innerHTML += "<br/>";}}//websocket出错自动调用websocketPage.onerror = function () {alert('websocket出错');}//关闭窗口前关闭websocket连接window.onbeforeunload = function (){websocketPage.close();}</script>
</html>

1.2、有前端向后端发送消息

在这里插入图片描述

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Java后端WebSocket的Tomcat实现</title><script type="text/javascript" src="js/jquery.min.js"></script></head><body>Welcome<br/><input id="text" type="text" /><button onclick="send()">发送消息</button><hr/><button onclick="closeWebSocket()">关闭WebSocket连接</button><hr/><div id="message"></div></body><script type="text/javascript">var websocket = null;//判断当前浏览器是否支持WebSocketif('WebSocket' in window) {//改成你的地址websocket = new WebSocket("ws://localhost:8080/websocket/100");} else {alert('当前浏览器 Not support websocket')}//连接发生错误的回调方法websocket.onerror = function() {setMessageInnerHTML("WebSocket连接发生错误");};//连接成功建立的回调方法websocket.onopen = function() {setMessageInnerHTML("WebSocket连接成功");}var U01data, Uidata, Usdata//接收到消息的回调方法websocket.onmessage = function(event) {console.log(event);if (event.data !== "conn_success"){setMessageInnerHTML("接收消息:"+event.data);// setMessageInnerHTML(event);setechart()}}//连接关闭的回调方法websocket.onclose = function() {setMessageInnerHTML("WebSocket连接关闭");}// //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function() {closeWebSocket();}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById('message').innerHTML += innerHTML + '<br/>';}//关闭WebSocket连接function closeWebSocket() {websocket.close();}//发送消息function send() {var message = document.getElementById('text').value;websocket.send('{"msg":"' + message + '"}');setMessageInnerHTML("--------------发送消息:"+message + "");}</script>
</html>

2、后端具体代码(spring boot)

2.1、maven依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

– yml没有东西,只有一个默认端口

2.2、配置类

需要加一个 WebSocket 端点暴露 的bean 和定时器注解

@EnableScheduling  //定时器
@SpringBootApplication
public class WebSocketApplication {public static void main(String[] args) {SpringApplication.run(WebSocketApplication.class, args);}/** * 服务器端点导出 * @author zhengfuping* @date 2023/8/22 * @return ServerEndpointExporter */@Beanpublic ServerEndpointExporter getServerEndpointExporter(){return new ServerEndpointExporter();}
}

3、Web Socket连接工具类

@Slf4j
@Service
@ServerEndpoint("/websocket/{uid}")
public class WebSocketServer2 {//连接建立时长private static final long sessionTimeout = 60000;// 用来存放每个客户端对应的WebSocketServer对象private static Map<String, WebSocketServer2> webSocketMap = new ConcurrentHashMap<>();// 与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;// 接收idprivate String uid;/*** 连接建立成功调用的方法* @author zhengfuping* @date 2023/8/22* @param session* @param uid*/@OnOpenpublic void onOpen(Session session , @PathParam("uid") String uid){session.setMaxIdleTimeout(sessionTimeout);this.session = session;this.uid = uid;if (webSocketMap.containsKey(uid)){webSocketMap.remove(uid);}webSocketMap.put(uid,this);log.info("websocket连接成功编号uid: " + uid + ",当前在线数: " + getOnlineClients());try{// 响应客户端实际业务数据!sendMessage("conn_success");}catch (Exception e){log.error("websocket发送连接成功错误编号uid: " + uid + ",网络异常!!!");}}/*** 连接关闭调用的方法* @author zhengfuping* @date 2023/8/22*/@OnClosepublic void onClose(){try {if (webSocketMap.containsKey(uid)){webSocketMap.remove(uid);}log.info("websocket退出编号uid: " + uid + ",当前在线数为: " + getOnlineClients());} catch (Exception e) {log.error("websocket编号uid连接关闭错误: " + uid + ",原因: " + e.getMessage());}}/*** 收到客户端消息后调用的方法* @param message 客户端发送过来的消息* @param session*/@OnMessagepublic void onMessage(String message, Session session) {try {WebSocketServer2.sendInfo(message);log.info("websocket收到客户端编号uid消息: " + uid + ", 报文: " + message);} catch (Exception e) {log.error("websocket发送消息失败编号uid为: " + uid + ",报文: " + message);}}/*** 发生错误时调用* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("websocket编号uid错误: " + this.uid + "原因: " + error.getMessage());error.printStackTrace();}/*** 实现服务器主动推送* @author yingfeng* @date 2023/8/22 10:11* @Param * @param null* @return*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 获取客户端在线数* @author zhengfuping* @date 2023/8/22 10:11* @param*/public static synchronized int getOnlineClients() {if (Objects.isNull(webSocketMap)) {return 0;} else {return webSocketMap.size();}}/*** 单机使用,外部接口通过指定的客户id向该客户推送消息* @param key* @param message* @return boolean*/public static boolean sendMessageByWayBillId(@NotNull String key, String message) {WebSocketServer2 webSocketServer = webSocketMap.get(key);if (Objects.nonNull(webSocketServer)) {try {webSocketServer.sendMessage(message);log.info("websocket发送消息编号uid为: " + key + "发送消息: " + message);return true;} catch (Exception e) {log.error("websocket发送消息失败编号uid为: " + key + "消息: " + message);return false;}} else {log.error("websocket未连接编号uid号为: " + key + "消息: " + message);return false;}}/*** 群发自定义消息* @author zhengfuping* @date 2023/8/22 9:52* @param message*/public static void sendInfo(String message) {webSocketMap.forEach((k, v) -> {WebSocketServer2 webSocketServer = webSocketMap.get(k);try {webSocketServer.sendMessage(message);log.info("websocket群发消息编号uid为: " + k + ",消息: " + message);} catch (IOException e) {log.error("群发自定义消息失败: " + k + ",message: " + message);}});}/*** 服务端群发消息-心跳包* @author zhengfuping* @date 2023/8/22 10:09* @param message 推送数据* @return int 连接数*/public static synchronized int sendPing(String message){if (webSocketMap.size() == 0)return 0;StringBuffer uids = new StringBuffer();AtomicInteger count = new AtomicInteger();webSocketMap.forEach((uid,server)->{count.getAndIncrement();if (webSocketMap.containsKey(uid)){WebSocketServer2 webSocketServer = webSocketMap.get(uid);try {if (Integer.valueOf(uid) ==101){Integer i=1/0;}webSocketServer.sendMessage(message);if (count.equals(webSocketMap.size() - 1)){uids.append("uid");return;}uids.append(uid).append(",");} catch (Exception e) {webSocketMap.remove(uid);log.info("客户端心跳检测异常移除: " + uid + ",心跳发送失败,已移除!");}}else {log.info("客户端心跳检测异常不存在: " + uid + ",不存在!");}});log.info("客户端心跳检测结果: " + uids + "连接正在运行");return webSocketMap.size();}/*** 连接是否存在* @param uid* @return boolean*/public static boolean isConnected(String uid) {if (Objects.nonNull(webSocketMap) && webSocketMap.containsKey(uid)) {return true;} else {return false;}}
}

2.3、Controller用于测试主动发送消息

@RestController
@RequestMapping("/test")
public class WebSocketController{/*** 检验连接* @date 2023/8/22* @Param * @param webSocketId* @return * @return String*/@GetMapping("/webSocketIsConnect/{webSocketId}")public String webSocketIsConnect(@PathVariable("webSocketId") String webSocketId){if (WebSocketServer2.isConnected(webSocketId)) {return webSocketId+"正在连接";}return webSocketId+"连接断开!";}/*** 单发 消息* @author zhengfuping* @date 2023/8/22 10:25* @param webSocketId  指定 连接* @param message  数据* @param pwd 验证密码* @return String*/@GetMapping("/sendMessageByWayBillId")public String sendMessageByWayBillId(String webSocketId, String message, String pwd) {boolean flag = false;flag = WebSocketServer2.sendMessageByWayBillId(webSocketId, message);if (flag) {return "发送成功!";}return "发送失败!";}/*** 群发* @author zhengfuping* @date 2023/8/22 10:26* @param message* @param pwd*/@GetMapping("/broadSendInfo")public void sendInfo(String message, String pwd) {WebSocketServer2.sendInfo(message);}
}

2.4、定时任务,用于调用主动向客户端发送心跳

每10秒调用一次,主动检测,查看客户端连接是否异常断开,如果异常断开,则把该会话从集合中剔除掉,避免无限积压。

@Component
@Slf4j
public class WebSocketTask {@Scheduled(cron = "0/10 * * * * ?")public void clearOrders(){int num = 0;try {num = WebSocketServer2.sendPing("conn_success");} finally {log.info("websocket心跳检测结果,共【" + num + "】个连接");}}
}

三、测试

1、 测试消息发送

1.1、前端日志

在这里插入图片描述

1.2、后端日志

在这里插入图片描述

2、测试客户端异常断开,服务器通过心跳检测自动剔除掉异常对话。

因为测试不方便,只能通过断点实现效果

  1. 前端需要把主动关闭会话的注释掉,不让主动关闭
    在这里插入图片描述

  2. 先在连接关闭的地方和心跳检测地方打上断点,断点需要设置成Thread,要不然没法异步
    在这里插入图片描述

  3. 然后关闭掉一个前端页面让他把会话关闭,就会进入该断点位置,通过断点让它停住不让他去正常关闭

在这里插入图片描述4. 然后选择执行该心跳检测的断点代码
在这里插入图片描述
5. 进入心跳的循环给每个会话发送心跳检测,此时前端已经异常断开了
在这里插入图片描述
6. 因为前端已经关闭会话了,则发送心跳会失败,会直接进入catch块,然后把该会话从集合中剔除掉
在这里插入图片描述
最终日志
在这里插入图片描述

相关文章:

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯&#xff08;包括后端实现心跳检测&#xff09; 一级目录二级目录三级目录 前言一、Web Socket 简绍1 为什么用 websocket&#xff1f; 二、代码实现1、前端&#xff08;html&#xff09;1.1、无前端向后端发送消息1.2、有前端向…...

node使用高版本的oracledb导致连接oracle的Error: NJS-138异常

异常信息如下 Error: NJS-138: connections to this database server version are not supported by node-oracledb in Thin mode 我的oracle版本是11g&#xff0c;之前的使用正常&#xff0c;今天却报错了&#xff0c;显示不支持thin模式&#xff0c;后面回退版本就可以了。...

RabbitMQ手动签收消息

RabbitMQ手动签收消息 这里讲解SpringBoot使用RabbitMQ进行有回调的用法和消费者端手动签收消息的用法。 1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"h…...

Unity 3d角色展示脚本(旋转 平移 缩放)展示界面

不考虑性能 很简陋的一个功能&#xff0c;主要是用于角色渲染的观察用&#xff0c;比simplecontroller要好用一点 using System; using UnityEngine;public class CharacterViewer : MonoBehaviour {public Transform target; // 人物模型的Transformpublic float rotationSpee…...

Spring Boot 将 Word 转换为 PDF

首先&#xff0c;确保项目中添加了对Apache POI和Apache PDFBox的依赖。可以在你的 pom.xml 文件中添加以下依赖&#xff1a; <dependencies><!-- Apache POI --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</arti…...

【PHP面试题82】system和exec是用来做什么的?有什么区别

文章目录 &#x1f680;一、前言&#xff0c;PHP中system和exec命令的作用&#x1f680;二、system()函数&#x1f680;三、exec()函数&#x1f680;四、区别和应用场景&#x1f50e;4.1 使用system()函数的应用场景&#x1f50e;4.2 使用exec()函数的应用场景&#x1f50e;4.3…...

05-微信小程序常用组件-表单组件

05-微信小程序常用组件-表单组件 文章目录 表单组件button 按钮案例代码 form 表单案例代码 image 图片支持长按识别的码案例代码 微信小程序包含了六大组件&#xff1a; 视图容器、 基础内容、 导航、 表单、 互动和 导航。这些组件可以通过WXML和WXSS进行布局和样式设…...

Lucky player —— Java 项目(Spring Boot)

一、项目介绍 项目名称&#xff1a;lucky player 项目的主要功能&#xff1a;本系统主要功能为构建了一个用户分享音乐的平台&#xff0c;普通用户不进行登录即可收听其他用户已经发布的专辑中的音乐。 作为博主则可以在该平台上传音频&#xff0c;以及在线音频录制上传。音频上…...

ios 声网agora 音视频直播场景下的集成总结

文章目录 一、前言二、视频会议场景2.1 场景描述2.2 功能列表三、电商直播场景3.1 场景描述3.2 功能列表3.3 技术方案四、声网iOS SDK集成4.1 集成4.2 示例demo4.3 核心代码4.3.1 初始化4.3.2 加入频道4.3.3 切换身份4.4.4 连麦4.4 相关问题4.4.1 监听观众角色用户事件五、相关…...

mysql 、sql server 临时表、表变量、

sql server 临时表 、表变量 mysql 临时表 创建临时表 create temporary table 表名 select 字段 [&#xff0c;字段2…&#xff0c;字段n] from 表...

15. Canvas制作汽车油耗仪表盘

1. 说明 本篇文章在14. 利用Canvas组件制作时钟的基础上进行一些更改&#xff0c;想查看全面的代码可以点击链接查看即可。 效果展示&#xff1a; 2. 整体代码 import QtQuick 2.15 import QtQuick.Controls 2.15Item{id:rootimplicitWidth: 400implicitHeight: implicitWi…...

解决git上传远程仓库时的最大文件大小限制

git默认限制最大的单文件100M&#xff0c;当某个文件到达50M时会给你提示。解决办法如下 首先&#xff0c;打开终端&#xff0c;进入项目所在的文件夹&#xff1b; 输入命令&#xff1a;git config http.postBuffer 524288000 执行完上面的语句后输入&#xff1a;git config…...

Midjourney API 国内申请及对接方式

在人工智能绘图领域&#xff0c;想必大家听说过 Midjourney 的大名吧&#xff01; Midjourney 以其出色的绘图能力在业界独树一帜。无需过多复杂的操作&#xff0c;只要简单输入绘图指令&#xff0c;这个神奇的工具就能在瞬间为我们呈现出对应的图像。无论是任何物体还是任何风…...

第一章 文件的输入和输出

一 创建一个文件,并写入数据 #include <stdio.h> int main(void) {FILE *fp;fp= fopen("test.txt","w+");fprintf...

java面试基础 -- 深克隆 浅克隆

引例 说到java的克隆你还记得多少? 一说到克隆你可能就会想起来那个接口, 没错, 他就是Cloneable Cloneable是java里面内置的很常用的接口, 我们说 Object类中也有一个clone方法: 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedEx…...

网络安全在医疗行业中的重要性

不可否认&#xff0c;现代世界见证了技术和医疗行业的交织&#xff0c;塑造了我们诊断、治疗和管理健康状况的新方式。随着电子健康记录取代纸质文件&#xff0c;远程医疗缩短了患者和医疗服务提供者之间的距离&#xff0c;数字化转型既是福音&#xff0c;也是挑战。最近的全球…...

elemenPlus ElMessage 字符串如何换行问题

因为后端返回的数据是一长串&#xff0c;而且带有\r,\n等换行符&#xff0c;但是并没有生效。前端写法&#xff1a; // 抛出错误ElMessage.error(msg);我们知道\r&#xff0c;\n&#xff0c;\r\n 是在不同系统下的换行符的表示&#xff0c;但在JavaScript返回字符串中并没有生效…...

Linux socket网络编程

一、主机字节序列和网络字节序列 主机字节序列分为大端字节序列和小端字节序列&#xff0c;不同的主机采用的字节序列可能不同。大端字节序列是指一个整数的高位字节存储在内存的低地址处&#xff0c;低位字节存储在内存的高地址处。小端字节序列是指整数的高位字节存储在内存…...

【广州华锐互动】牲畜养殖VR模拟实操系统为传统教育注入新的生命力

随着科技的不断发展&#xff0c;虚拟现实(VR)技术已经逐渐走进我们的生活。在农业领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为现代农业人才培养提供了新的途径。 由广州华锐互动开发的“牲畜养殖VR模拟实操系统”引起了广泛关注&#xff0c;系统包含了鸡、猪、牛、马…...

JavaScript基础(Dom操作)

目录 一&#xff0c;BOM模型1.1&#xff0c;BOM可实现功能 二&#xff0c;Window对象的常用属性2.1&#xff0c;Window对象的常用方法2.1-1&#xff0c;open()和close()方法 三&#xff0c;History对象四&#xff0c;Location对象五&#xff0c;Document对象的常用方法六&#…...

.NET6.0 System.Drawing.Common 通用解决办法

最近有不少小伙伴在升级 .NET 6 时遇到了 System.Drawing.Common 的问题&#xff0c;同时很多库的依赖还都是 System.Drawing.Common &#xff0c;而 .NET 6 默认情况下只在 Windows 上支持使用&#xff0c;Linux 上默认不支持这就导致在 Linux 环境上使用会有问题&#xff0c;…...

k8s ingress (二)

k8s ingress (二) Ingress介绍 在前面课程中已经提到&#xff0c;Service对集群之外暴露服务的主要方式有两种&#xff1a;NodePort和LoadBalancer&#xff0c;但是这两种方式&#xff0c;都有一定的缺点&#xff1a; NodePort方式的缺点是会占用很多集群机器的端口&#xff0…...

如何实现element UI中table操作栏更多按钮的展示与折叠?

解决思路: ​ 直接使用elementUI文档上Popover 弹出框组件 废话不多说,直接上代码吧 <el-table :data="locationList" v-loading="loading" border class="table" ref="multipleTable" @selection-change="handleSelecti…...

SpringBoot(二)

###SpringBoot原理分析 ###SpringBoot监控 ###SpringBoot项目部署 #SpringBoot自动配置 Condition&#xff1a;&#xff08;条件&#xff09; Condition是在Spring4.0增加的条件判断功能&#xff0c;通过这个功能可以实现选择性的创建Bean操作 SpringBoot是如何知道要创建…...

python脚本——批量将word文档转换成pdf文件

语言&#xff1a;python 3 用法&#xff1a;点击运行后&#xff0c;弹出窗口选择word文档所在文件夹&#xff0c;程序运行后对该文件夹下所有的word文件全部转换成pdf文件&#xff0c;生成的pdf文件名字与原wrod文件相同。 如运行中报错&#xff0c;需要自行根据报错内容按照…...

自然语言处理从入门到应用——LangChain:链(Chains)-[通用功能:链的保存(序列化)与加载(反序列化)]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 本文介绍了如何将链保存&#xff08;序列化&#xff09;到磁盘和从磁盘加载&#xff08;反序列化&#xff09;。我们使用的序列化格式是json或yaml。目前&#xff0c;只有一些链支持这种类型的序列化。随着时间的推移&…...

机器学习:开启智能时代的重要引擎

引言 随着科技的飞速发展&#xff0c;人工智能已经渗透到我们生活的各个领域。而在人工智能的众多领域中&#xff0c;机器学习以其强大的数据处理能力和智能决策能力受到了广泛关注。本文将向您介绍机器学习的概念、工作原理、应用领域以及未来的发展前景。 一、什么是机器学…...

ES搭建集群

一、创建 elasticsearch-cluster 文件夹 创建 elasticsearch-7.8.0-cluster 文件夹&#xff0c;在内部复制三个 elasticsearch 服务。 然后每个文件目录中每个节点的 config/elasticsearch.yml 配置文件 node-1001 节点 #节点 1 的配置信息&#xff1a; #集群名称&#xff0…...

# Lua与C++交互(二)———— 交互

C 调用lua 基础调用 再来温习一下 myName “beauty girl” C想要获取myName的值&#xff0c;根据规则&#xff0c;它需要把myName压入栈中&#xff0c;这样lua就能看到&#xff1b;lua从堆栈中获取myName的值&#xff0c;此时栈顶为空&#xff1b;lua拿着myName去全局表中查…...

机器人焊接生产线参数监控系统理解需求

机器人焊接生产线参数监控系统是以参数来反映系统状态并以直观的方式表现 出来&#xff0c;及时了解被监视对象的状态和状态的变化情况。其主要目标是为了达到减少 生产线的处理时间&#xff0c;降低故障率&#xff0c;缩短故障排除时间&#xff0c;从而提高生产线的生产效率 …...

wordpress 建站 视频 百度云/摘抄一小段新闻

举例&#xff1a; 注意&#xff1a;在声明中函数的第二个参数给定了缺省值NULL&#xff0c;如果调用时候不指定具体参数&#xff0c;程序则按NULL处理&#xff0c;如果指定了具体值&#xff0c;则按照实际处理。下面是使用例子。 这样处理可以节省代码。解决有时候需要两个重载…...

中企做的网站/南宁seo计费管理

也许你已经知道了&#xff0c;我们正在招聘最优秀的程序员。不错&#xff0c;每个人都这样说。但是我们的程序员能打败你们的——任何时候。比如&#xff0c;米奇虽然只有5英尺高&#xff0c;但他是一个有相当实力的击剑手。维托尔德以前是一个6’3″的职业冰球选手。内特喜欢以…...

商城网站怎么做/如何做好线上推广

当前云桌面厂家虽然有很多但是就按类别来说我们可以把它分为两大类的&#xff0c;一类就是服务器在本地的私有云桌面&#xff0c;还有一类就是服务器不在本地的公有云桌面。那么他们两者之间到底有什么不一样的呢&#xff0c;我们是选择私有云桌面好还是公有云桌面更好的呢&…...

长沙开福区专业制作网站/长春网站制作推广

Xilinx FPGA bit 文件加密 今天给大侠带来Xilinx FPGA bit 文件加密设计&#xff0c;话不多说&#xff0c;上货。 当你的项目终于做完了&#xff0c;到了发布的关键节点&#xff0c;为了防止自己的心血被别人利用&#xff0c;最好对产品进行bit加密。 首先咱们来了解一下加密…...

一家专门做特卖的网站/廊坊网络推广公司

OctoberCMS ———— 十月之秋 --一个基于laravel的快速集成开发框架 十月CMS是一个轻量级的&#xff0c;回到建立在Laravel基本的内容管理系统&#xff0c;并在执行任务&#xff0c;使您的Web开发工作流程再容易。它拥有一个非常简单和快速的学习曲线&#xff0c;以保证你会离…...

wordpress图像描述/如何优化搜索引擎的准确性

理解AdamW 我们先弄清楚什么是weight decay 其实是在损失函数求导后&#xff0c;放在正则项前面的系数&#xff0c;比如L2正则&#xff0c;我们看一下weight decay的位置 我们可以认为λ就是weightdecaymin⁡wL2(w)min⁡wf(w)λ2n∑i1nwi2L2′(w)f′(w)λn∑i1nwi我们可以认为…...