Greetings |
---|
STOMP源于需要通过脚本语言(例如Ruby,Python和Perl)连接到企业消息代理的需求。在这样的环境中,通常在逻辑上执行简单的操作,例如“可靠地发送单个消息并断开连接”或“在给定目的地上消耗所有消息”。
它是其他开放消息协议(例如AMQP)和JMS代理(例如OpenWire)中使用的实现特定有线协议的替代。它通过覆盖一小部分常用消息传递操作而不提供全面的消息传递API来与众不同。
STOMP协议是和AMQP,JMS消息协议是平级的是应用层的协议,STOMP是可以建立在WebSocket协议上面的,
一个STOMP帧由三部分组成: 命令,Header(头信息),Body(消息体)
一个STOMP客户端是一个可以以两种模式运行的用户代理,可能是同时运行两种模式。
在客户端和服务端连接发送消息的命令有以下几种
都是建立在连接成功的情况下, 客户端想发送到服务端
连接成功的情况下 服务端想发送到客户端
org.springframework.boot
spring-boot-starter-websocket
org.springframework
spring-messaging
package com.example.demo.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;
@Configuration
// @EnableWebSocketMessageBroker注解用于开启使用STOMP协议来传输基于代理(MessageBroker)的消息,这时候控制器(controller)
// 开始支持@MessageMapping,就像是使用@requestMapping一样。
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//注册一个 Stomp 的节点(endpoint),并指定使用 SockJS 协议。
registry.addEndpoint("/sendStomp").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 广播式配置名为 topic 和 queue
// topic一般用于广播推送
// queue用于点对点推送
registry.enableSimpleBroker("/topic","/queue");
// 如果设置 前段请求过来必须带上 带上这个才会被 controller 拦截 (发送路径上体现)
registry.setApplicationDestinationPrefixes("/server");
// 点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
// registry.setUserDestinationPrefix("/user/");
}
}
package com.example.demo.request;
import lombok.Data;
/**
* @Classname ClientRequest
* @Description
* @Date 2021/3/19 14:35
* @Created by dongzhiwei
*/
@Data
public class ClientRequest {
/**
* 用户名
*/
private String name;
}
response
package com.example.demo.response;
import lombok.Data;
/**
* @Classname ServerResponse
* @Description 服务端返回
* @Date 2021/3/19 14:35
* @Created by dongzhiwei
*/
@Data
public class ServerResponse {
public ServerResponse() {
}
public ServerResponse(String message) {
this.message = message;
}
private String message;
}
package com.example.demo.controller;
import com.example.demo.request.ClientRequest;
import com.example.demo.response.ServerResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Controller;
/**
* @Classname WebSocketController
* @Description ws 的controller
* @Date 2021/3/19 14:33
* @Created by dongzhiwei
*/
@Controller
@Slf4j
public class WebSocketController {
/**
* 这个模板 可以发送到 客户端订阅的路径上,
* 也就是调用这个发 必须要客户端先通过 subscribe 订阅这个地址
*/
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/hello") // @MessageMapping 和 @RequestMapping 功能类似,浏览器向服务器发起请求时,映射到该地址。
public ServerResponse say(ClientRequest message) throws Exception {
Thread.sleep(1000);
simpMessagingTemplate.convertAndSend("/queue/5214521/subscribeTest","谢谢你hello");
return new ServerResponse("Hello,"+message);
}
/**
* 订阅点
*
*/
@SubscribeMapping("/subscribeTest")
public ServerResponse sub() {
log.info("XXX用户订阅了我。。。");
return new ServerResponse("感谢你订阅了我。。。");
}
}
如果spring boot 可以访问 web页面 可以通过 thymeleaf 实现 加依赖
org.springframework.boot
spring-boot-starter-thymeleaf
application.properties 里面配置访问路径
spring.thymeleaf.prefix=classpath:/public/
页面的代码
Hello WebSocket
Greetings
这个对代码的侵入性比较高 但是涉及到有业务逻辑相关的 用这个也还行