集成基于Websocket的Stomp连接

本篇文章主要就是记录一下前后端如何集成STOMP连接

  • 后端是通过java+springboot+Stomp
  • 前端是sockJS+Stomp

最原始的需求是在cocos里面使用长连接进行消息通信,毕竟游戏的场景下,服务端通知客户端是很常见的,用http满足不了,只能使用socket进行通信。

简单介绍一下Stomp(Simple Text Oriented Messaging Protocol),是一种基于websocket之上的简洁通信协议。

怎么选择的stomp呢

作为java开发,那肯定是springboot了,新建springboot项目

 在组件依赖里面选择websocket,组件的简介看完大家应该明白了,就是集成了SockJS和STOMP,这里说一下,springboot的版本使用2.x,3.x要求jdk17,我本地装的老古董jdk1.8,所以只能2.x

这里的两个链接很重要,第一个是简单的教程地址,第二个是详细的教程地址,我就是从这个地址开始自学的(主要是百度搜出来的教程太乱了,看多了反而更糊涂)

回答一下小标题,怎么选中的stomp呢,主要就是发现springboot已经集成了stomp,本着拿来主义精神,选了stomp。

简易教程

这里的简易教程就是把官方的简易教程实现了一下

第一步:配置maven

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.1-1</version>
        </dependency>
如果只是作为服务端,那么spring-boot-starter-websocket这个jar包是必须的,其他的jar都是为了示例,因为前后端放在一起了,其他包都是前端需要的

第二步:添加config

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
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;

/**
 * websocket的配置类
 * @author dfg
 * @date 2023-04-28 21:50
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // 客户端接收服务器消息的地址前缀
        config.enableSimpleBroker("/topic");
        // 客户端给服务端发消息的地址前缀
        config.setApplicationDestinationPrefixes("/app");
    }

    /**
     * 注册端点
     * setAllowedOrigins 支持跨域
     * withSockJS 支持socketJs
     * @param registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").setAllowedOriginPatterns("*").withSockJS();
    }
}

注释已经写清楚了,只是这里有一个知识点需要了解一下,一直在说Stomp,那他到底是怎么通信的呢

这是官方的原理图,解读一下就两条线和两个很重要的类

  • 客户端发送目的地是/app/a的消息,服务端收到之后发现是/app的消息,给到SimpAnnotationMethod类处理,返回一个目的地是/topic/a的消息,给到SimpleBroker类,查找所有订阅了/topic/a这个目的地的客户端,广播消息
  • 客户端发送目的地是/topic/a的消息,服务端收到之后一看是/topic消息,直接给到SimpleBroker类,然后查找&广播一样的流程
  • SimpAnnotationMethodMessageHandler:接收消息的处理类
  • SimpleBrokerMessageHandler:发送消息的处理类

了解了原理,在看配置信息就清晰了

第三步:编写controller

package com.example.messagingstompwebsocket;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

@Controller
public class GreetingController {


  @MessageMapping("/hello")
  @SendTo("/topic/greetings")
  public Greeting greeting(HelloMessage message) throws Exception {
    Thread.sleep(1000); // simulated delay
    return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
  }

}

看到上述代码,了解web编程的应该很熟悉了,只是返回结果是一个广播的形式,订阅了的客户端都能收到,上述两个重要注解@MessageMapping("/hello")最终接收得目的地是/app/hello@SendTo("/topic/greetings")发送的目的地就是/topic/greetings

第四步:前端代码

完整部分自行看教程,我把重要部分复制了出来

// 引入sockjs与stomp
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>

// 连接
function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        // 订阅目的地是/topic/greetings的消息
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

// 发送目的地是/app/hello的消息
function sendName() {
    stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}

 最后介绍一种用法

后端的controller

package com.example.messagingstompwebsocket;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

@Controller
public class GreetingController {


  @MessageMapping("/hello/{groupId}")
  @SendTo("/topic/greetings/{groupId}")
  public Greeting greeting(@DestinationVariable String groupId, HelloMessage message) throws Exception {
    Thread.sleep(1000); // simulated delay
    return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
  }

}

注解里面支持占位符,例如是群组聊天,通过生成一个groupId,给组里面的所有人发送消息

指定用户发送查看下一个进阶篇

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值