spring boot 后台的配置
这里记录一些坑
使用 gradle 配置, 其中移除了 Tomcat , 使用的是 Undertow
先引入依赖
implementation ('org.springframework.boot:spring-boot-starter-websocket')
提示报错 web 容器没有实现 JSR356
undertow 肯定是实现了 JSR356, 在 undertow-websockets-jsr 这个依赖里
判断肯定是由于移除 Tomcat 的问题,查看依赖发现 spring-boot-starter-websocket
依赖了 web , 而 web 默认使用的就是 Tomcat
于是移除 web 依赖即可
1 2 3
| implementation ('org.springframework.boot:spring-boot-starter-websocket'){ exclude group: 'org.springframework.boot', module: 'spring-boot-starter-web' }
|
代码部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override public void configureMessageBroker(MessageBrokerRegistry config) {
}
@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOrigins("*") .withSockJS(); }
}
|
注意在启动类上加入: @EnableWebSocketMessageBroker
这里使用的是 stomp 协议, 于是也要前端使用 stomp 配合
发送消息可以加入 @SendTo 注解, 还有一种方式, 就是使用 SimpMessagingTemplate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @RestController @RequestMapping("ws") public class PushMessage {
private final SimpMessagingTemplate template;
public PushMessage(SimpMessagingTemplate template) { this.template = template; }
@GetMapping("/config") public void configMessage() { template.convertAndSend("/topic/public", MessageBody.success()); } }
|
React 配置
安装组件 npm install react-stomp
自行封装一个组件,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React, {Component} from 'react'; import SockJsClient from "react-stomp"; import {message} from "antd";
class Websocket extends Component {
render() { return ( <div> <SockJsClient url={'ws'} topics={[]} onMessage={(payload) => { console.info(payload) }} onConnect={() => { console.info("websocket connect success") }} onConnectFailure={() => { message.error("websocket 连接失败!") }} onDisconnect={() => { console.info("websocket disconnect") }} debug={false} {...this.props} /> </div> ); } }
export default Websocket;
|
子组件使用:
1 2 3 4 5 6 7
| <Websocket topics={['/topic/public']} debug={false} onMessage={(payload) => { }} />
|
遇坑解决
以上方式看起来使用没有问题,但是现实情况往往开发时前后端分离,请求后端接口往往在 node 项目里配置代理, 这里涉及到 websocket 的代理
之前的配置都是在 package.json 配置, 比如:
1
| "proxy": "http://localhost:8098"
|
但是这种方式对 websocket 的代理失败,会发现 websocket 连接不上
解决方式:
在新版的 customize-cra 的使用方式里:
先安装 http-proxy-middleware : npm install http-proxy-middleware
在 src 目录下新建文件 setupProxy.js, 名字不可改,一定要是这个文件名
1 2 3 4 5 6 7 8 9 10 11 12
| const proxy = require("http-proxy-middleware"); const pck = require('../package');
module.exports = app => { app.use( proxy("/ws", { target: pck.proxy, ws: true }) ) };
|
这里开启 ws: true 即可完成 websocket 的代理.