Spring Boot——整合WebSocket(基于STOMP协议)

WebSocket 与HTTP 的简单区别:

  • HTTP 每次请求应答都需要客户端与服务端建立连接的模式;
  • HTTP 是一种由客户端到服务端的单向通信协议;
  • .WebSocket 是一种双向通信协议,WebSocket 服务器和Browser/Client Agent 都能主动的向对方发送或接收数据;
  • 两种请求的方式不同,一种是ws(wss)另一种是http(https)

WebSocket 简单使用:

1.添加pom文件依赖:
        
        
            org.springframework.boot
            spring-boot-starter-websocket
        
2.直接上源码:
@Repository
public class MyHandler extends TextWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("获取到消息》》》》" + message.getPayload());
        session.sendMessage(new TextMessage("消息已收到"));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        session.sendMessage(new TextMessage("欢迎连接到ws服务"));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("断开连接");
    }
}

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    MyHandler myHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(this.myHandler,"/ws").setAllowedOrigins("*");
    }
}
3.我们可以通过在线测试工具进行测试:
Spring Boot——整合WebSocket(基于STOMP协议)_第1张图片

基于STOMP协议的WebSocket的使用:

它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互,类似于OpenWire(一种二进制协议)

STOMP协议工作于TCP协议之上,使用了下列命令:
  • SEND 发送
  • SUBSCRIBE 订阅
  • UNSUBSCRIBE 退订
  • DISCONNECT 断开
1.一样先WebSocket的添加pom文件依赖
2.配置websocket stomp(代码中均有做解释)
/**
 * 通过EnableWebSocketMessageBroker
 * 开启使用STOMP协议来传输基于代理(message broker)的消息,
 * 此时浏览器支持使用@MessageMapping 就像支持@RequestMapping一样。
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    /**
     * 注册stomp的端点
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
        //endPoint 注册协议节点,并映射指定的URl点对点-用
        //注册一个名字为"endpointChat" 的endpoint,并指定 SockJS协议。
        //允许使用socketJs方式访问,访问点为webSocketServer,允许跨域
        registry.addEndpoint("/endpointChat")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    /**
     * 配置消息代理(message broker)
     * @param registry
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {//配置消息代理(message broker)
        //订阅Broker名称:topic 代表发布广播,即群发
        //queue 代表点对点,即发指定用户
        registry.enableSimpleBroker("/queue", "/topic");
        // 全局使用的消息前缀(客户端订阅路径上会体现出来)
        registry.setApplicationDestinationPrefixes("/app");
        //点对点使用的订阅前缀(客户端订阅路径上会体现出来),
        // 不设置的话,默认也是/user/
        // registry.setUserDestinationPrefix("/user/");
    }
}
3.消息实体类

客户端发往服务器端实体类(可自定义)

public class RequestMessage {
    private String name;

    public String getName() {
        return name;
    }
}

服务器端发往客户端实体类(可自定义)

public class ResponseMessage {
    private String responseMessage;

    public String getResponseMessage() {
        return responseMessage;
    }

    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }

    public ResponseMessage() {

    }
    public ResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
}
4.控制层
@Controller
public class WebSockedController {

    /**
     * @param requestMessage
     * @return
     * @MessageMapping 指定要接收消息的地址,类似@RequestMapping。除了注解到方法上,也可以注解到类上
     * @SendTo默认 消息将被发送到与传入消息相同的目的地
     */
    @MessageMapping("/sendTest")
    @SendTo("/topic/subscribeTest")
    public ResponseMessage broadcast(RequestMessage requestMessage) {
        ResponseMessage responseMessage = new ResponseMessage();
        responseMessage.setResponseMessage("你发送的消息为:" + requestMessage.getName());
        return responseMessage;
    }

    @SubscribeMapping("/subscribeTest")
    public ResponseMessage sub() {
        ResponseMessage responseMessage = new ResponseMessage();
        responseMessage.setResponseMessage("感谢你订阅了我");
        return responseMessage;
    }

    @Autowired
    SimpMessagingTemplate template;

    @GetMapping("/indexaaa")
    @ResponseBody
    public Result gg() {
        template.convertAndSend("/topic/getResponse", new ResponseMessage("通过SimpMessagingTemplate进行消息广播该方式无法直接被使用,需要建立连接后访问使用,"));

        return Result.success();
    }

    @RequestMapping(value = "/index")
    public String broadcastIndex(HttpServletRequest req) {
        System.out.println(req.getRemoteHost());
        return "index";
    }

}
5.前端代码



    
    测试


websocket!!!!




6.功能详解

@MessageMapping(“/sendTest”)
接收客户端发送的消息,当客户端发送消息的目的地为/app/sendTest时,交给该注解所在的方法处理消息,其中/app是在WebSocketConfig配置文件configureMessageBroker方法中添加:
registry.setApplicationDestinationPrefixes("/app");
若没有添加@SendTo注解且该方法有返回值,则返回的目的地地址为/topic/sendTest,经过消息代理,客户端需要订阅了这个主题才能收到返回消息

@SubscribeMapping(“/subscribeTest”)
接收客户端发送的订阅,当客户端订阅的目的地为/app/subscribeTest时,交给该注解所在的方法处理订阅,其中/app为客户端请求前缀
若没有添加@SendTo注解且该方法有返回值,则返回的目的地地址为/app/sendTest,不经过消息代理,客户端需要订阅了这个主题才能收到返回消息

@SendTo(“/topic/subscribeTest”)
修改返回消息的目的地地址为/topic/subscribeTest,经过消息代理,客户端需要订阅了这个主题才能收到返回消息

通过@SubscribeMapping 、SimpMessagingTemplate (服务器主动推送)的形式所订阅的地址结果(如果点击关闭WebSocket连接后将无法获取订阅消息)
Spring Boot——整合WebSocket(基于STOMP协议)_第2张图片
通过@SendTo所订阅的地址结果
Spring Boot——整合WebSocket(基于STOMP协议)_第3张图片
整理的不是很全不过点对点传输也是如此,在send连接中多一个/user即可实现,只不过在后端需要注意差别,该笔记有参考过网上一些博客前辈的写法,若有不足之处还欢迎指点!!!

你可能感兴趣的:(Spring Boot——整合WebSocket(基于STOMP协议))