上一篇已经写了一个传统方式的websocket实现,在浏览过程看到也有使用stomp 方式 所以很想尝试一下 代码里面有详细使用的说明

主要代码

后端代码

配置

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;

/**

* @Author: lkz

* @Title: WebSocketBrokerConfig

* @Description: 另外一种方法

* //@EnableWebSocketMessageBroker注解表示开启使用STOMP协议来传输基于代理的消息,Broker就是代理的意思。

* @Date: 2022/10/14 9:42

* https://github.com/JustCoding-Hai/subtlechat-vue/wiki/3.%E4%BD%BF%E7%94%A8websocket%E5%AE%9E%E7%8E%B0%E7%BE%A4%E8%81%8A

*/

@Configuration

@EnableWebSocketMessageBroker

public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {

/**

* 配置消息代理,哪种路径的消息会进行代理处理

* configureMessageBroker方法用来配置消息代理,由于我们是实现推送功能,这里的消息代理是/topic

* 作用:1.消息代理会处理前缀为“/topic”的消息

* 2.客户端发送到服务端的消息需要带有“/app”前缀

* @param registry

* //在topic和user这两个域上服务端可以向客户端发消息 设置广播节点

* registry.enableSimpleBroker("/topic", "/user");

* //客户端向服务器端发送时的主题上面需要加"/app"作为前缀

* registry.setApplicationDestinationPrefixes("/app");

* //服务端给客户端指定用户发送一对一的主题,前缀是"/user"

* registry.setUserDestinationPrefix("/user");

*/

@Override

public void configureMessageBroker(MessageBrokerRegistry registry) {

//服务端发送消息将消息传入带有topic开头订阅的客户端 ,

registry.enableSimpleBroker("/topic");

// 客户端发送消息时 ,需要以app作为前缀

registry.setApplicationDestinationPrefixes("/app"); //这个是客户端发消息时使用 ,作用不同于 registry.addEndpoint()

}

/**

* 作用:注册STOMP协议的节点(端点),并指定映射的URL。

* 将“/ws/websocket”注册为端点,客户端订阅消息或发送消息到目的地前要连接该端点

* 添加这个Endpoint,这样在网页中就可以通过websocket连接上服务,也就是我们配置websocket的服务地址,并且可以指定是否使用socketjs

* @param registry

*/

@Override

public void registerStompEndpoints(StompEndpointRegistry registry) {

//注册STOMP协议节点,同时指定使用SockJS协议。

registry.addEndpoint("/wsWeb") // 确保客户端可以正常连接,同@ServerEndpoint("/ws")方式一样 如果有安全拦截 放行即可

.setAllowedOrigins("*") //处理跨域 单体需要打开 微服务如果在网关中配置了就不需要

.withSockJS();

}

/**

* 上面以ws的消息都会被路由到带有@MessageMapping

* 以topic的消息都会发送到STOMP代理中,给根据所选择的stomp代理不同,选择的前缀也有限制

* 以user开头的消息会将消息重路由到某个用户独有的目的地上

* 接收客户端发来的消息,参数就是消息本身message

* @MessageMapping 或者 @SubscribeMapping 注解可以处理客户端发送过来的消息,并选择方法是否有返回值。

* @MessageMapping 指定目的地是“/app/test”(“/app”前缀是隐含的,因为我们将其配置为应用的目的地前缀)。

* 通信协议可以自定义——可自定义参数的格式

* 可以接收json格式的数据,传递josn数据时不需要添加额外注解@Requestbody

* 消息发送者不是从前端传递过来的,而是从springsecurity中获取的,防止前端冒充

* 如果 @MessageMapping 注解的控制器方法有返回值的话,返回值会被发送到消息代理,只不过会添加上"/topic"前缀。

* 通过为方法添加@SendTo注解,重载目的地

*

* @MessageMapping 用在@Controller注解的类中,根据目的地路由消息的方法

*

* @SendTo 自定义要将有效内容发送到的目标,一般用于广播消息

*

* @SendToUser 是仅向与消息关联的用户发送消息

*

*/

}

控制层

@Controller

public class WebsocketController {

@Resource

private SimpMessagingTemplate simpMessagingTemplate;

@MessageMapping("/test")

public void test(String message){

System.out.println("接收到客户端发送来的消息:"+message);

simpMessagingTemplate.convertAndSend("/topic/sub",message); // 前端订阅

}

}

后端控制台

前端代码

首先vue需要安装依赖 stomp js 和sockjs依赖 ,我感觉只要安装stomp依赖即可

npm install --save stompjs

在需要使用的地方导入

import SockJS from "sockjs-client";

import Stomp from "stompjs";

主要业务代码

myInfo(){

// this.initWebsocket();

this.initStompSocket();

},

//websocket 相关开始

// stomp方式

initStompSocket(){

//使用sockjs建立连接,并发起请求

var stompClients= Stomp.over(new SockJS("http://localhost:8603"+"/wsWeb",null,{timeout: 15000}));

this.stompClient=stompClients;

// 连接成功回调 参考请求头填 待测试 https://www.cnblogs.com/wwxdxgb/p/16261720.html

// const headers={

// Authorization: ""

// }

// 参考 方法 https://www.likecs.com/ask-2883310.html?sc=1800

stompClients.connect({},success=>{

//订阅服务端发送过来的消息 这里是广播

console.log("连接成功")

// 同下面的都可以发送,唯一不同的是 箭头函数指向当前对象,function,如果使用this指向的当前window ,调用下面的发送消息 会找不到方法 ,所以function函数的时候 我是用的是stompClients本身

//stompClients.subscribe("/topic/sub",function (msg) {

this.stompClient.subscribe("/topic/sub", msg=> {

console.log('成功订阅到消息:'+msg.body)

//同时发送一条消息给服务端

var token= getCookie("token");

var st="订阅成功后发送的数据";

// this.sendMsg(st) // 下面这两种方式都是往服务端发送消息 主要是测试使用 不然会一直发送消息,接收消息

//stompClients.send("/app/test",{},JSON.stringify(st))

});

//点对点 一般用于发送指定用户 ,可以自行百度

// this.stompClient.subscribe("/user",function (msg) {

// //this.stompClient.subscribe("/topic/sub", msg=> {

// console.log('成功订阅到消息:'+msg.body)

// //同时发送一条消息给服务端

// var token= getCookie("token");

// var st="订阅成功后发送的数据";

// // this.sendMsg(st)

// })

},fail=>{

console.log("建立连接失败")

//异常时重连

// if(this.stompCount>10){

// console.log("温馨提示: 您的连接已经断开,请重新登录")

// this.stompCount=0;

// }else{

// this.wsReconnect && clearTimeout(this.wsReconnect);

// this.wsReconnect = setTimeout(function () {

// console.log("开始重连...");

// this.initStompSocket();

// console.log("重连完毕...");

// this.stompCount++;

// }, 1000);

// }

this.stompClient.disconnect();

})

},

//这里是方便调用 发送的消息转换格式发送 确保后端能收到信息

sendMsg(data){

this.stompClient.send("/app/test",{},JSON.stringify(data))

},

控制台打印结果

参考的博客: https://blog.csdn.net/u013041642/article/details/108154230 https://fulongyuanjushi.blog.csdn.net/article/details/123970860 https://blog.csdn.net/qq_43581790/article/details/124791002

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: