SpringBoot : ch07 整合websocket

前言

当涉及到在Spring Boot应用程序中整合WebSocket时,我们可以使用Spring框架提供的功能来实现实时双向通信。WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它允许服务器主动向客户端发送消息,而不需要客户端发起请求。

在本博客中,我们将探讨如何在Spring Boot应用程序中使用WebSocket来建立实时通信。我们将通过一个简单的示例来演示如何配置和使用WebSocket,以及如何处理客户端与服务器之间的消息传递。

首先,我们将介绍WebSocket的基本概念和工作原理,然后引入Spring WebSocket模块,并展示如何配置和启用WebSocket支持。接下来,我们将创建一个WebSocket控制器,处理客户端连接和消息的收发。最后,我们将创建一个前端页面来展示实时通信的效果。

一、WebSocket的基本概念和工作原理

WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它允许服务器主动向客户端发送消息,而不需要客户端发起请求。相比于传统的基于HTTP的轮询技术,WebSocket可以实现更加高效、实时的双向通信。

WebSocket的基本概念和工作原理如下:

1.握手阶段

在WebSocket连接建立之前,需要进行一次握手过程。客户端向服务器发送一个HTTP请求,请求头中包含了Upgrade和Connection字段,表明客户端希望将当前的HTTP连接升级为WebSocket连接。服务器收到请求后,验证请求头信息并响应一个HTTP 101 Switching Protocols响应,表示升级成功,此时WebSocket连接建立完成。

2.数据传输阶段

WebSocket连接建立后,客户端和服务器之间可以进行双向通信。客户端和服务器都可以随时向对方发送消息,并且不需要进行额外的请求和响应。通信过程中,数据以二进制或文本的形式进行传输。

3.断开连接阶段

当客户端或服务器想要关闭WebSocket连接时,可以发送一个特殊的关闭帧,表示结束通信。接收到关闭帧后,对方也会发送一个关闭帧进行确认。之后,WebSocket连接会被断开,通信终止。

总的来说,WebSocket的工作原理可以概括为以下几个步骤:握手阶段建立连接、数据传输阶段双向通信、断开连接阶段结束通信。WebSocket的优点在于它可以实现低延迟、高效的实时双向通信,适用于需要及时响应和交互的应用场景,如在线游戏、在线聊天等。

 

 二、前期准备

1、新建项目,结构如下

2、导入依赖
  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

 这是一个典型的Spring Boot项目的pom.xml文件示例,其中包含了与WebSocket相关的依赖项以及其他常见的依赖项。让我为您解释一下这些依赖项的作用:

  1. spring-boot-starter-websocket: 这个依赖项提供了Spring WebSocket模块的基本功能,包括WebSocket协议的支持和相关的类库。

  2. org.projectlombok:lombok: 这是一个可选的依赖项,用于简化Java代码的编写。它可以通过注解自动生成getter、setter和其他常见的方法,减少样板代码的编写量。

  3. spring-boot-starter-test: 这个依赖项提供了Spring Boot应用程序的测试支持,包括自动化单元测试和集成测试等。

接下来是<build>部分,其中包含了用于构建和打包应用程序的插件配置。具体来说:

  1. spring-boot-maven-plugin: 这个插件可以将Spring Boot应用程序打包为可执行的JAR文件,并提供了其他与构建和运行相关的配置选项。

在这个示例中,还对插件进行了特定的配置。<image>元素指定了用于构建容器镜像的基础镜像,<excludes>元素指定了在镜像构建过程中排除的依赖项,这里排除了lombok。

这是一个基本的pom.xml文件示例,用于构建一个使用WebSocket的Spring Boot应用程序。您可以根据自己的需求进行修改和扩展。

三、配置 WebSocketConfig 配置类

@Configuration
public class WebsocketConfig {

    /**
     * 装配 ServerEndpointExporter
     * 会自动注册带有 @ServerEndpoint 注解的类
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

}

这段代码展示了一个典型的WebSocket配置类,通常用于将WebSocket端点暴露给Spring容器。让我为您解释一下这段代码的作用:

  1. @Configuration: 这个注解表明这是一个配置类,它会在Spring应用程序启动时被加载,并且可以包含用@Bean注解标记的方法用于定义bean。

  2. WebsocketConfig: 这是配置类的类名,用于定义WebSocket相关的配置。

  3. @Bean: 这个注解用于将方法返回的对象注册为Spring应用程序上下文中的bean,使其可以被其他组件自动注入和使用。

  4. serverEndpointExporter(): 这是一个@Bean方法,用于创建并返回一个ServerEndpointExporter对象。ServerEndpointExporter是Spring提供的用于扫描带有@ServerEndpoint注解的类并注册其实例的类,从而将其暴露为WebSocket端点。

总的来说,这段代码的作用是创建一个配置类,并在其中定义了一个@Bean方法用于注册ServerEndpointExporter,以便自动注册带有@ServerEndpoint注解的类作为WebSocket端点。这样做可以使得WebSocket端点能够被Spring容器正确管理并且与WebSocket通信进行交互。

四、编写实体类

1、User 实体类
@Data
public class User {

    private String userName;

}

 用于登录,保存登录的用户名称。

 2、Message 实体类
@Data
public class Message {

    /**
     * 发送人
     */
    private String sendUser;

    /**
     * 发送消息
     */
    private String message;

}

封装发送消息的内容和发送人。

五、完成登录及页面

1、登录后台代码

@Controller
public class LoginController {

    /**
     * 登录并将用户保存到会话中,重定向到聊天页面
     * @param user
     * @param session
     * @return
     */
    @PostMapping("/user/login")
    public String login(User user, HttpSession session){
        session.setAttribute("user",user);
        return "redirect:/chat.html";
    }

}

 这段代码展示了一个简单的Spring MVC控制器,用于处理用户登录请求并将用户保存到会话中。让我为您解释一下这段代码的作用:

  1. @Controller: 这个注解标识了这个类是一个Spring MVC控制器,它可以处理来自客户端的HTTP请求并返回相应的视图或数据。

  2. LoginController: 这是控制器类的类名,用于处理用户登录请求。

  3. @PostMapping("/user/login"): 这个注解指定了处理POST类型的"/user/login"请求的方法,即当用户提交登录表单时,将调用这个方法进行处理。

  4. public String login(User user, HttpSession session): 这个方法接收一个User对象和HttpSession对象作为参数,表示从用户提交的表单中获取用户信息,并将用户信息保存到会话中。

  5. session.setAttribute("user",user);: 这行代码将用户对象保存到会话中,以便在后续的WebSocket通信中可以使用用户信息进行身份验证和授权等操作。

  6. return "redirect:/chat.html";: 这行代码将HTTP响应重定向到聊天页面(chat.html),即当用户登录成功后,将跳转到聊天页面进行实时通信。

2、登录页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户登录</h1>

<form method="post" action="user/login">
    Name:<input type="text" name="userName" />
    <input type="submit" value="登录">
</form>

</body>
</html>
  1. <form method="post" action="user/login">: 这个标签定义了一个HTML表单,并指定了提交方法为POST,提交地址为"user/login",即当用户点击登录按钮时,将向"/user/login"地址发送POST请求。

  2. Name:<input type="text" name="userName" />: 这行代码创建了一个输入框,用于用户输入用户名。

  3. <input type="submit" value="登录">: 这行代码创建了一个提交按钮,用于用户提交登录表单。

3、 聊天页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/JQuery文件.txt.js"></script>
</head>
<body>
<h2>聊天室</h2>
<div id="content"></div>
<form id="f1">
    <input type="text" id="message"/>
    <input type="button" value="发送"/>
</form>


</body>
</html>
4、效果
 

六、实现聊天功能

1、服务器端

@Slf4j
@Component
@ServerEndpoint(value = "/connect",configurator = HttpSessionConfigutator.class)
public class ChatServer {

    /**
     * 用户列表
     */
    private static Map<String, Session> users = new HashMap<>();

    @OnOpen
    public void onOpen(Session session){
        // 获取登录的用户
        User user = (User) session.getUserProperties().get("user");
        // 保存到用户列表中
        users.put(user.getUserName(),session);
    }

    /**
     * 接收消息并群发
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message,Session session) throws JsonProcessingException {
        // 获取发送人
        User sendUser = (User) session.getUserProperties().get("user");
        // 封装消息对象
        Message message1 = new Message();
        message1.setSendUser(sendUser.getUserName());
        message1.setMessage(message);

        // 序列化成 JSON 字符串
        String json = new ObjectMapper().writeValueAsString(message1);
        // 群发
        users.forEach((userName,sess) -> {
            try {
                sess.getBasicRemote().sendText(json);
            } catch (IOException e) {
                throw new RuntimeException("发送失败",e);
            }
        });
    }

    /**
     * 用户离线移除在线用户
     * @param session
     */
    @OnClose
    public void onClose(Session session){
        User user = (User) session.getUserProperties().get("user");
        log.info(user.getUserName() + ":已离线");
        // 从用户列表移除这个用户
        users.remove(user.getUserName());
    }


}

这段代码是一个基于Java的WebSocket服务器端实现,用于创建一个聊天服务器。让我为您解释一下这段代码的作用:

  1. @Slf4j:这是一个Lombok注解,用于自动生成日志记录器。

  2. @Component:这是一个Spring注解,将该类声明为一个可被Spring容器管理的组件。

  3. @ServerEndpoint(value = "/connect",configurator = HttpSessionConfigutator.class):这是一个Java WebSocket注解,它将这个类声明为一个WebSocket端点,指定了连接的URL路径为"/connect",并且配置了一个HttpSessionConfigutator来支持获取HttpSession。

  4. private static Map<String, Session> users = new HashMap<>():这是一个静态变量,用于存储用户列表。它使用用户名作为键,WebSocket会话对象Session作为值。

  5. @OnOpen:这是一个Java WebSocket注解,它表示当有新的WebSocket连接打开时,会调用这个方法。在这个方法中,通过从会话的UserProperties中获取登录的用户,然后将用户保存到用户列表中。

  6. @OnMessage:这是一个Java WebSocket注解,它表示当接收到WebSocket消息时,会调用这个方法。在这个方法中,首先获取发送人的用户对象,然后封装成消息对象Message。接着使用ObjectMapper将消息对象序列化为JSON字符串,然后通过遍历用户列表,将消息发送给每个在线用户。

  7. @OnClose:这是一个Java WebSocket注解,它表示当WebSocket连接关闭时,会调用这个方法。在这个方法中,首先获取离线用户的用户对象,然后从用户列表中移除该用户。

总体来说,这段代码实现了一个简单的聊天服务器,通过WebSocket协议实现实时的消息传递功能。当有用户连接到服务器时,将其加入用户列表;当接收到用户发送的消息时,将消息群发给所有在线用户;当用户离线时,将其从用户列表中移除。

2、握手连接处理类 

public class HttpSessionConfigutator extends Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        //获取HttpSession
        HttpSession session = (HttpSession) request.getHttpSession();
        //获取登录用户的信息
        User user = (User) session.getAttribute("user");
        //再将用户信息保存到websocket的session的属性中
        sec.getUserProperties().put("user", user);
    }

}

这个类是一个自定义的WebSocket配置器,它实现了javax.websocket.server.ServerEndpointConfig.Configurator接口。它的作用是在WebSocket握手期间修改握手请求和响应,以便将用户信息从HttpSession传递到WebSocket的会话中。

具体来说,这个类重写了modifyHandshake方法,在WebSocket握手期间被调用。在这个方法中,它首先通过request.getHttpSession()方法获取到当前的HttpSession对象,然后从HttpSession中获取登录用户的信息。接着,它将用户信息保存到WebSocket会话的属性中,使用sec.getUserProperties().put("user", user)语句将用户信息存储在user键下。

通过这样的操作,WebSocket会话就可以在握手成功后获取到用户信息,并且可以在后续的处理过程中使用该信息。这种方式可以实现将用户身份信息从HttpSession传递到WebSocket会话的目的,方便在WebSocket处理逻辑中使用用户信息。

3、客户端代码实现
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/JQuery文件.txt.js"></script>
</head>
<body>
<h2>聊天室</h2>
<div id="content"></div>
<form id="f1">
    <input type="text" id="message"/>
    <input type="button" value="发送"/>
</form>
<script>
    //实例化ws对象
    let ws = new WebSocket('ws://localhost:8080/connect');
    //接收服务端的消息
    ws.onmessage = function(event) {
        //先将json字符串转换为json对象
        let data = $.parseJSON(event.data);
        //将消息追加到内容区
        $('#content').append(data.sendUser + ' : ' + data.message + '<br>')
    }
    //发送消息
    $(function(){
        $(':button').on('click', function(){
            let msg = $('#message').val();
            //通过ws发送
            ws.send(msg);
            //清空发送框
            $('#message').val('');
        });
    })
</script>

</body>
</html>
  1. <div id="content"></div>:用于显示聊天内容的区域。
  2. <form id="f1">:定义一个表单,用于输入消息内容。
  3. <input type="text" id="message"/>:文本输入框,用于输入消息。
  4. <input type="button" value="发送"/>:按钮,用于发送消息。
  5. let ws = new WebSocket('ws://localhost:8080/connect');:创建WebSocket对象,连接到服务器的WebSocket地址。
  6. ws.onmessage = function(event) { ... }:当接收到服务端的消息时,执行其中的代码。
  7. let data = $.parseJSON(event.data);:将接收到的消息数据解析为JSON对象。
  8. $('#content').append(data.sendUser + ' : ' + data.message + '<br>'):将发送者和消息内容追加到聊天内容区域。
  9. $(function(){ ... }):当页面加载完成后执行其中的代码。
  10. $(':button').on('click', function(){ ... }):当按钮被点击时执行其中的代码。
  11. let msg = $('#message').val();:获取输入框中的消息内容。
  12. ws.send(msg);:通过WebSocket发送消息给服务器。
  13. $('#message').val('');:清空输入框的内容。

这段代码实现了一个简单的前端聊天室界面,通过WebSocket与后端服务器进行通信,实现了即时的消息收发功能。用户可以在输入框中输入消息,点击发送按钮后,消息会发送给服务器,并显示在聊天内容区域中。同时,页面会接收到其他用户发送的消息,并将其展示在聊天内容区域中。

4、运行效果

七、springboot整合WebSocket的好处

将Spring Boot与WebSocket整合的好处如下:

  1. 实时性:WebSocket提供了双向通信的能力,使得服务器能够主动推送消息给客户端,而不需要客户端不断地发送请求。这样可以实现实时的消息传递,适用于聊天室、即时通讯等场景。

  2. 减少网络开销:相比传统的轮询方式,WebSocket减少了不必要的网络开销。客户端只需要与服务器建立一次连接,之后就可以保持长连接,避免了频繁的请求和响应。

  3. 提高性能:通过减少网络开销和降低服务器负载,WebSocket可以提高系统的整体性能。相比使用HTTP协议进行轮询的方式,WebSocket在消息传输过程中的开销更小,更高效。

  4. 简化开发:Spring Boot框架提供了对WebSocket的良好支持,简化了WebSocket的开发流程。开发者可以通过注解和配置快速实现WebSocket功能,减少了繁琐的手动配置和编码工作。

  5. 跨平台支持:WebSocket是一种基于标准的通信协议,得到了广泛的支持。无论是Web端还是移动端,都可以方便地使用WebSocket进行通信,实现跨平台的即时通讯。

综上所述,Spring Boot整合WebSocket可以提供实时性、性能优化和开发简化等好处,适用于需要实时通信的应用场景。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

23种经典设计模式:单例模式篇(C++)

前言&#xff1a; 博主将从此篇单例模式开始逐一分享23种经典设计模式&#xff0c;并结合C为大家展示实际应用。内容将持续更新&#xff0c;希望大家持续关注与支持。 什么是单例模式&#xff1f; 单例模式是设计模式的一种&#xff08;属于创建型模式 (Creational Pa…

多功能智慧路灯系统整体解决方案介绍

在不改变现有城市景观的前提下&#xff0c;利用现有路灯改造&#xff0c;或新建多功能叁仟智慧路灯的方法&#xff0c;可实现城市无线网络、视频监控、物联传感网络、新能源充电系统、网格信息化管理的全覆盖&#xff0c;有效解决信息化设备选址难、取电难等问题。在目前无线通…

87基于matlab的双卡尔曼滤波算法

基于matlab的双卡尔曼滤波算法。第一步使用了卡尔曼滤波算法&#xff0c;用电池电压来修正SOC&#xff0c;然后将修正后的SOC作为第二个卡尔曼滤波算法的输入&#xff0c;对安时积分法得到的SOC进行修正&#xff0c;最终得到双卡尔曼滤波算法SOC估计值。结合EKF算法和安时积分法…

pytorch实现遥感建筑物提取

如何自动地从高分辨率遥感影像中提取建筑物等人工目标是高分辨率遥感影像处理与理解领域的一个热点与难点问题。本篇文章我们将学习如何使用pytorch实现遥感建筑物的智能提取。 智能提取的流程 基于深度学习的遥感建筑物智能提取&#xff0c;首先需要制作数据集&#xff0c;然后…

【Java数据结构 -- 包装类和泛型】

包装类和泛型 1. 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱1.4 自动装箱实际上是调用了valueOf&#xff08;&#xff09;1.5 Integer包装类赋值注意点 2 什么是泛型3 引出泛型4 泛型的使用4.1 语法4.2 类型推导 5 裸类型6 泛型如何编译6.1 擦…

C++-继承

一. 继承的概念及定义 1 . 继承的概念 继承(inheritance) 机制是面向对象程序设计 使代码可以复用 的最重要的手段&#xff0c;它允许程序员在 保 持原有类特性的基础上进行扩展 &#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承 呈现了面向对象 程…

亚马逊、eBay店铺如何提升销量转化?掌握测评自养号的技巧

跨境电商随着互联网和物流技术的迅速发展&#xff0c;消费者可以更轻松地借助跨境电商平台在全球范围内进行购物&#xff0c;而提到跨境电商&#xff0c;亚马逊平台是不可忽视。 在竞争激烈的亚马逊市场中&#xff0c;提升销量转化率是每个卖家都追求的目标&#xff0c;高转化…

企业被列入经营异常会有什么后果?

1、工商方面的不良影响 被工商纳入异常吊销营业执照&#xff1a;公司地址异常将会被工商部门纳入经营异常名录&#xff0c;需要及时申请移出&#xff0c;否则会影响正常经营&#xff0c;严重则有被吊销营业执照的风险。 影响企业形象及信誉度&#xff1a;企业间的合作都非常重视…

git报错:error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413

git报错&#xff1a;error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 如图&#xff1a; error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 send-pack: unexpected disconnect while reading sideband packet fatal: th…

【C语言】【选择排序及其优化】

选择排序是指&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;然后再从剩余的未排序元素中寻找到最小&#xff08;大&#xff09;元素&#xff0c;然后放到已排序的序列的末尾&#xff0…

代码随想录算法训练营第六十天|84. 柱状图中最大的矩形

LeetCode 84. 柱状图中最大的矩形 题目链接&#xff1a;84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 和接雨水还挺像的。 代码&#xff1a; #python class Solution:def largestRectangleArea(self, heights: List[int]) -> int:heights.insert(0, 0…

Intel Software Guard Extensions简介

文章目录 前言一、新的基于硬件的控件实现数据安全二、机密计算的挑战三、用于机密计算的增强安全功能四、Enclave验证和数据密封五、数据中心认证参考资料 前言 最近开始研究Intel SGX硬件特性&#xff0c;记录下研究过程。 参考文档&#xff1a;product-brief-SGX 一、新的…

python实现自动刷平台学时

背景 前一阵子有个朋友让我帮给小忙&#xff0c;因为他每学期都要看视频刷学时&#xff0c;一门平均需要刷500分钟&#xff0c;一学期有3-4门需要刷的。 如果是手动刷的话&#xff0c;比较麻烦&#xff0c;能否帮他做成自动化的。搞成功的话请我吃饭。为了这顿饭&#xff0c;咱…

Redis的五大数据类型详细用法

我们说 Redis 相对于 Memcache 等其他的缓存产品&#xff0c;有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据&#xff0c;同时还提供list&#xff0c;set&#xff0c;zset&#xff0c;hash等数据结构的存储。本篇博客我们就将介绍这些数据类型的详细使用…

Javaweb之Vue组件库Element之Dialog对话框的详细解析

4.3.3 Dialog对话框 4.3.3.1 组件演示 Dialog: 在保留当前页面状态的情况下&#xff0c;告知用户并承载相关操作。其企业开发应用场景示例如下图所示 首先我们需要在ElementUI官方找到Dialog组件&#xff0c;如下图所示&#xff1a; 然后复制如下代码到我们的组件文件的templ…

「江鸟中原」有关HarmonyOS-ArkTS的Http通信请求

一、Http简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在Web应用程序之间进行通信的协议&#xff0c;通过运输层的TCP协议建立连接、传输数据。Http通信数据以报文的形式进行传输。Http的一次事务包括一个请求和一个响应。 Http通信是基于客户端-服…

Go 数字类型

一、数字类型 1、Golang 数据类型介绍 Go 语言中数据类型分为&#xff1a;基本数据类型和复合数据类型基本数据类型有&#xff1a; 整型、浮点型、布尔型、字符串复合数据类型有&#xff1a; 数组、切片、结构体、函数、map、通道&#xff08;channel&#xff09;、接口 2、…

Redux在React中的使用

Redux在React中的使用 1.构建方式 采用reduxjs/toolkitreact-redux的方式 安装方式 npm install reduxjs/toolkit react-redux2.使用 ①创建目录 创建store文件夹&#xff0c;然后创建index和对应的模块&#xff0c;如上图所示 ②编写counterStore.js 文章以counterStore…

C语言入门---位操作

目录 1. 两个数不同的二进制位个数 2.原码、反码、补码 3.不创建临时变量实现两个数的交换 4.求一个整数存储在内存中的二进制中1的个数 5. 特例-1 6.将指定的位置置1 7.将指定位置置1 8.a与a 9.||与&& 10.逗号表达式 11.srand与rand 12.sizeof 13.结构体初始…

时间序列预测实战(二十)自研注意力机制Attention-LSTM进行多元预测(结果可视化,自研结构)

一、本文介绍 本文给大家带来的是我利用我自研的结构进行Attention-LSTM进行时间序列预测&#xff0c;该结构是我专门为新手和刚入门的读者设计&#xff0c;包括结果可视化、支持单元预测、多元预测、模型拟合效果检测、预测未知数据、以及滚动长期预测&#xff0c;大家不仅可…
最新文章