SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息

这篇具有很好参考价值的文章主要介绍了SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息

参考:

1、https://www.mchweb.net/index.php/dev/887.html

2、https://itonline.blog.csdn.net/article/details/81221103?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-81221103-blog-121078449.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-81221103-blog-121078449.pc_relevant_aa&utm_relevant_index=1

3、https://blog.csdn.net/yingxiake/article/details/51224569

使用场景

广播模式 :使用场景:给所有连接了这个通道的客户端发送消息。

  • convertAndSend()
  • @SendTo

点对点模式 :使用场景:单独给当前用户发送消息。

  • 下面两种方式,都默认加了一个前缀:/user

  • convertAndSendToUser()

  • @SendToUser

一、后端SpringBoot + WebSocket基础配置

1、导包

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2、配置config

  • 细节:必须配置跨域。低版本的SpringBoot(2.1.5.RELEASE 就不行)不行,需要使用高版本。低版本的解决方案还未找到。
  • 跨域配置使用:.setAllowedOriginPatterns("*")。。不能使用:.setAllowedOrigins("*")
package com.cc.ws.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * <p>@EnableWebSocketMessageBroker 的作用</p>
 * <li>注解开启使用STOMP协议来传输基于代理(message broker)的消息,</li>
 * <li>这时控制器支持使用 @MessageMapping,就像使用 @RequestMapping一样</li>
 * @author cc
 *
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    /** <p>启动简单Broker</p>
     * <p>表示客户端订阅地址的前缀信息,也就是客户端接收服务端消息的地址的前缀信息</p>
     * <p>代理的名字:都是自定义的</p>
     *
     * /user     点对点(默认也是/user,可以自定义,但是必须和setUserDestinationPrefix中的设置一致)
     * /topic1   广播模式1
     * /topic2   广播模式2
     *
     * /mass     广播模式:群发
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker(
                "/user", "/topic1", "/topic2", "/mass"
        );
        // 点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是 /user/
        // 注意,这里必须和上面设置的Broker:/user 一致(两个都可以自定义,但必须一致)。否则连接不上
        registry.setUserDestinationPrefix("/user/");
        // 指服务端接收地址的前缀,意思就是说客户端给服务端发消息的地址的前缀
//        registry.setApplicationDestinationPrefixes("/socket");
    }

    /**
     * 这个方法的作用是添加一个服务端点,来接收客户端的连接。
     * registry.addEndpoint("/socket")表示添加了一个/socket端点,客户端(前端)就可以通过这个端点来进行连接。
     * withSockJS()的作用是开启SockJS支持。
     * @param registry registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 注册一个STOMP的endpoint端点,并指定使用SockJS协议
        // 前端使用这个地址连接后端 WebSocket接口
        registry.addEndpoint("/broadcast", "/point")
                // 允许所有源跨域。还可以指定ip配置:http://ip:*
                // 低版本的SpringBoot(2.1.5.RELEASE 就不行)不行
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }

}

3、启动类,配置定时器

  • @EnableScheduling
@SpringBootApplication
@EnableScheduling
public class WebSocketDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebSocketDemoApplication.class, args);
    }
}

二、前端基础配置

    let socket1 = new SockJS('http://服务器ip:服务器端口/broadcast');
   
    let stompClient1 = Stomp.over(socket1);//广播模式

    stompClient1.connect({}, (frame) => {
      stompClient1.subscribe('/topic1/', (message) => {
        console.log(message.body);
      });
    });

三、后端不接收,只发送

  • 使用spring Scheduled 定时发送消息

  • 直接使用:SimpMessagingTemplate 的 convertAndSend广播模式 和 convertAndSendToUser点对点模式

1、后端

  • 注意点对点发送:

convertAndSendToUser的默认前缀(/user)是在WebSocketConfig配置文件中配置的。

代码:文章来源地址https://www.toymoban.com/news/detail-450540.html

    @Resource
    private SimpMessagingTemplate simpMsgTemp;

    /** 广播推送消息1:会发送给所有连接了 topic1 这个通道的客户端。
     * topic1:在Broker中配置
     **/
    @Scheduled(cron = "0/1 * * * * ?")
    public void getSocket(){
        String msg = String.format("%s 的第 %s 个消息", "topic1", LocalDateTime.now().getSecond());
        log.info("{}",msg);
        simpMsgTemp.convertAndSend("/topic1/", msg);
    }

    /** 广播推送消息2:多指定一个uri。相当于另一条通道(推荐使用)
     * <li>自定义url后缀,还可以实现用户和用户单点发送。</li>
     * topic2:在Broker中配置
     * custom:是自定义的
     */
    @Scheduled(cron = "0/1 * * * * ?")
    public void getSocketUser(){
        String msg = String.format("topic2 的第 %s 个消息", LocalDateTime.now().getSecond());
        log.info("{}",msg);
        simpMsgTemp.convertAndSend("/topic2/custom" ,msg);
    }

    /**点对点发送 convertAndSendToUser(第一个参数:一般是用户id)
     *  -> 假如用户id是1。用用户id是1的在两个地方登陆了客户端(比如不同的浏览器登陆同一个用户),
     *  -> convertAndSendToUser会把消息发送到用户1登陆的两个客户端中
     * 发送到:/user/{userId}/cs 下。cs是自定义的,且必须自定义一个。
     */
    @Scheduled(cron = "0/1 * * * * ?")
    public void pointToPoint(){
        //这个用户id是后端获取的当前登陆的用户id
        String userId = "123";
        String msg = String.format("点对点:第 %s 个消息。用户id:%s", LocalDateTime.now().getSecond(), userId);
        log.info("{}",msg);
        //发送
        simpMsgTemp.convertAndSendToUser(userId,"/cs/" ,msg);
    }

2、前端

  • 注意点对点的接收方式,用户id需要取出前端存的用户id
    //这样才能同时接收后端来的三套不同通道的消息。
    // broadcast 和后端:registerStompEndpoints中的配置必须一致
    // point     和后端:registerStompEndpoints中的配置必须一致
    // broadcast、point 也可以只用一个,这里只是为了好区分。
    let socket1 = new SockJS('http://yourIp:端口/broadcast');
    let socket2 = new SockJS('http://yourIp:端口/broadcast');
    let socket3 = new SockJS('http://yourIp:端口/point');
    // console.log("wb:" + socket)

    let stompClient1 = Stomp.over(socket1);
    let stompClient2 = Stomp.over(socket2);
    let stompClient3 = Stomp.over(socket3);

    // ----------------广播模式1--------------------
    stompClient1.connect({}, (frame) => {
      console.log('-----------frame1', frame)
      stompClient1.subscribe('/topic1/', (message) => {
        console.log(message.body);
        this.msg = message.body;
        // console.log(JSON.parse(message.body));
      });
    });

    // ----------------广播模式2--------------------
    stompClient2.connect({}, (frame) => {
      console.log('-----------frame2', frame)
      stompClient2.subscribe('/topic2/custom', (message) => {
        console.log(message.body);
        this.user = message.body;
        // console.log(JSON.parse(message.body));
      });
    });

    // ----------------点对点模式--------------------
    //前端获取的 userId
    let userId = '123';
    //连接WebSocket服务端
    stompClient3.connect({},(frame) => {
      console.log('Connected:' + frame);
      stompClient3.subscribe('/user/' + userId + '/cs/',
          (response) => {
            this.peer = response.body;
      });
    });

四、后端接收、接收后再发送

  • 也可以只接收消息,不发送。看业务需求。
  • 使用 @MessageMapping 接收前端发送过来的消息
  • 使用:@SendTo 广播模式、@SendToUser 点对点模式
  • 使用:SimpMessagingTemplate 的 convertAndSend广播模式 和 convertAndSendToUser 点对点模式

1、后端

    @Resource
    private SimpMessagingTemplate simpMsgTemp;

    /** <p>广播模式一、接收前端的消息,处理后给前端返回一个消息。</p>
     * <li>后端 把消息处理后 发送到 /mass/getResponse 路径下</li>
     * <ol>
     *     <li>@MessageMapping("/massRequest1") :作用:接收前端来的消息。类似于@RestController</li>
     *     <li>@SendTo("/mass/getResponse1"):作用跟convertAndSend类似,广播发给与该通道相连的客户端。SendTo 发送至 Broker 下的指定订阅路径 </li>
     *     <li>@SendToUser("/mass/getResponse1"):作用跟convertAndSendToUser类似,定点发送。SendTo 发送至 Broker 下的指定订阅路径 </li>
     *     <li>/mass 必须在配置文件配置</li>
     *     <li>/getResponse1 自定义的后缀</li>
     * </ol>
     */
    @MessageMapping("/massRequest1")
    @SendTo("/mass/getResponse1")
    public String mass1(String chatRoomRequest){
        //处理前端消息……
        log.info("前端消息:{}",chatRoomRequest);
        //返回消息
        return "@SendTo 广播一(单次) 后端处理完成!";
    }

    /** 广播模式二、接收前端的消息,可以多次给前端发消息
     * <li>/mass 必须在配置文件配置</li>
     * <li>/getResponse2 自定义的后缀</li>
     */
    @MessageMapping("/massRequest2")
    public void mass2(String chatRoomRequest){
        log.info("前端的消息:{}",chatRoomRequest);

        for (int i = 0; i < 5; i++) {
            String msg = "后端处理后的 广播二(多次):" + i;
            simpMsgTemp.convertAndSend("/mass/getResponse2", msg);
        }
        simpMsgTemp.convertAndSend("/mass/getResponse2",
                "后端处理后的 广播二(多次),后端处理完成!");
    }

    /** <p>点对点一、接收前端消息,只能返回一次消息(必须登陆系统才能使用。)</p>
     * <li>只有发送原始消息的客户端才会收到响应消息,而不是所有连接的客户端都会收到响应消息。</li>
     * <li>/alone/getResponse1:自定义的,不需要在配置文件配置。</li>
     *
     * <p>@SendToUser</p>
     * <li>默认该注解前缀为 /user</li>
     * <li>broadcast属性,表明是否广播。就是当有同一个用户登录多个session时,是否都能收到。取值true/false.</li>
     *
     * @param principal Principal :登陆用户的信息,需要使用spring s安全框架写入信息?
     */
    @MessageMapping("/aloneRequest1")
    @SendToUser("/alone/getResponse1")
    public String alone1(String chatRoomRequest){
        //处理前端消息……
        log.info("前端消息:{}",chatRoomRequest);
        //返回消息
        return "@SendToUser 点对点一(单次) 后端处理完成!";
    }

    /** 点对点二、接收前端消息,可以多次给前端发消息
     * <li>convertAndSendToUser —— 发送消息给指定用户id的</li>
     * <li>如果用户1在两个地方(A/B)登陆可以客户端,并且连接了该通道,其中一个如A给后端发消息,后端返回消息,A/B两个地方都会收到消息</li>
     * <ol>
     *     <li>@MessageMapping("/aloneRequest2") 接收前端指定用户消息,</li>
     *     <li>/alone/getResponse2 不用在配置文件中配置</li>
     *     <li>返回消息 发送到 user/{userId}/alone/getResponse2 下 (定点发送)</li>
     * </ol>
     */
    @MessageMapping("/aloneRequest2")
    public void alone2(String chatRoomRequest){
        //后端获取的当前登陆的用户的id(和前端一致)
        String userId = "456";
        log.info("前端的消息:{}",chatRoomRequest);

        for (int i = 0; i < 5; i++) {
            String msg = "后端处理后的 点对点二(多次):" + i;
            simpMsgTemp.convertAndSendToUser(userId,"/alone/getResponse2", msg);
        }
        simpMsgTemp.convertAndSendToUser(userId,"/alone/getResponse2",
                "后端处理后的 点对点二(多次),后端处理完成!");
    }

2、前端

  • 3点对点一 未实现。
    //连接SockJS的 broadcast
    let socket1 = new SockJS('http://yourIp:端口/broadcast');
    let socket2 = new SockJS('http://yourIp:端口/broadcast');
    let socket3 = new SockJS('http://yourIp:端口/point');
    let socket4 = new SockJS('http://yourIp:端口/point');
    //使用STMOP子协议的WebSocket客户端
    let stompClient1 = Stomp.over(socket1);
    let stompClient2 = Stomp.over(socket2);
    let stompClient3 = Stomp.over(socket3);
    let stompClient4 = Stomp.over(socket4);

    //1广播模式一
    stompClient1.connect({},(frame) => {
      console.log('广播模式一:' + frame);
      //1发送消息
      stompClient1.send("/massRequest1",{},"我是前端来 广播模式一 的消息!");

      //2接收消息
      stompClient1.subscribe('/mass/getResponse1',(response) => {
        this.broadcast1 = response.body
      });
    });

    //2广播模式二
    stompClient2.connect({},(frame) => {
      console.log('广播模式二:' + frame);
      //1发送消息
      stompClient2.send("/massRequest2",{},"我是前端来 广播模式二 的消息");

      //2接收消息
      stompClient2.subscribe('/mass/getResponse2',(response) => {
        this.broadcast2 = response.body
      });
    });

    //3点对点一 :必须登陆系统才能实现。要往:Principal设置用户登陆信息才行
    //1发送消息
    // stompClient3.send("/aloneRequest1",{},"我是前端来 点对点一 的消息");
    stompClient3.connect({},(frame) => {
      console.log('点对点一1:' + frame);
      stompClient3.send("/aloneRequest1",{},"我是前端来 点对点一 的消息");
      //2接收消息
      stompClient3.subscribe('/user/alone/getResponse1' ,(response) => {
        console.log('-------response.body', response.body)
        this.point1 = response.body
      });
    });

    //4点对点二:必须获取现在登陆了的用户id,且必须和后端一致才行。
    stompClient4.connect({},(frame) => {
      console.log('点对点二:' + frame);
      //1发送消息
      stompClient4.send("/aloneRequest2",{},"我是前端来 点对点二 的消息");

      //2接收消息
      //前端获取的当前登陆的用户userId(和后端一致)
      let userId = '456';
      stompClient4.subscribe('/user/'+userId+'/alone/getResponse2',(response) => {
        this.point2 = response.body
      });
    });

到了这里,关于SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 207、SpringBoot 整合 RabbitMQ 实现消息的发送 与 接收(监听器)

    1、ContentUtil 先定义常量 2、RabbitMQConfig 创建队列的两种方式之一: 配置式: 在容器中配置 org.springframework.amqp.core.Queue 类型的Bean,RabbitMQ将会自动为该Bean创建对应的队列。 就是在配置类中创建一个生成消息队列的@Bean。 问题: 用 @Configuration 注解声明为配置类,但是项目启动

    2024年02月06日
    浏览(57)
  • Java Websocket发送文件给Vue客户端接收并上传,实现检测U盘插入并将指定文件上传到服务器功能

    应用环境: B/S架构 需求描述: 1、判断U盘接入 2、扫描U盘指定文件,将满足条件的文件发送给服务器 解决思路: 1、因为bs架构,无法获取本机资源,计划在U盘所在服务器部署websocket服务 2、websocket服务扫描u盘,拿到指定文件,使用session.getBasicRemote().sendBinary(data)分批发送二

    2024年01月15日
    浏览(56)
  • vue+springboot+websocket实现消息通知,含应用场景

    vue、springboot 实现场景 点击同步之后更新数据,更新时间比较长,因此使用异步,之后该按钮置灰,在数据更新完成之后,服务端通知客户端已经同步成功,通知提示框,用户即可查看数据 前端 1、在对应的页面编写初始化、连接成功,错误,接受信息方法 2、mounted或者cre

    2024年02月11日
    浏览(77)
  • Kafka消息队列实现消息的发送和接收

    消息在Kafka消息队列中发送和接收过程如下图所示: 消息生产者Producer产生消息数据,发送到Kafka消息队列中,一台Kafka节点只有一个Broker,消息会存储在Kafka的Topic(主题中),不同类型的消息数据会存储在不同的Topic中,可以利用Topic实现消息的分类,消息消费者Consumer会订阅

    2024年02月11日
    浏览(52)
  • Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息

    Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息 回调函数处理

    2024年02月13日
    浏览(61)
  • 「RabbitMQ」实现消息确认机制以确保消息的可靠发送、接收和拒收

    目录 介绍 方案 配置手动确认 使用 「Bean 」 配置RabbitMQ的属性 确定消费、拒绝消费、拒绝消费进入死信队列 模拟生产者发送消息①         RabbitMQ 的消息确认机制应用场景非常广泛,尤其是在需要确保消息可靠性和避免消息丢失的场合下更为重要,例如:金融系统、电

    2024年02月08日
    浏览(39)
  • Java 实现使用 Websocket 发送消息

    需求背景:之前做了个楼栋房间数量出租了多少,需要在数据大屏上实时展示 解决方案:以切面拦截出租接口,当有房间出租时重新查询相关数据,封装好用websocket实时传送前端展示 提示:以下是本篇文章正文内容,下面案例可供参考 WebSocket 是一种在单个TCP连接上进行全双

    2024年03月27日
    浏览(42)
  • 实战指南:使用Spring Boot实现消息的发送和接收

    当涉及到消息发送和接收的场景时,可以使用Spring Boot和消息中间件RabbitMQ来实现。下面是一个简单的示例代码,展示了如何在Spring Boot应用程序中创建消息发送者和接收者,并发送和接收一条消息。 首先,你需要进行以下准备工作 确保你已经安装了Java和Maven,并设置好相应

    2024年02月11日
    浏览(53)
  • 使用Java服务器实现UDP消息的发送和接收(多线程)

    在本篇博客中,我们将介绍如何使用Java服务器来实现UDP消息的发送和接收,并通过多线程的方式来处理并发请求。UDP(User Datagram Protocol)是一种无连接、不可靠的传输协议,适合于实时性要求高的应用场景,如实时游戏、语音通信等。 步骤: 首先,我们需要导入Java提供的

    2024年02月12日
    浏览(47)
  • 如何在Java实现TCP方式发送和接收Socket消息(多线程模式)

    在Java编程中,使用TCP协议进行Socket通信是非常常见的场景。本文将详细介绍如何在Java中实现TCP方式发送和接收Socket消息,并且利用多线程模式来提高通信效率。 首先,我们需要创建一个Server端来处理接收到的Socket连接请求。以下是实现的步骤: 创建一个ServerSocket对象,并指

    2024年02月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包