springboot与vue中webSocket前后端连接问题
写在最前:在项目中发现前端在连接后端服务器websocket时,使用127.0.0.1IP访问一切正常,到生产环境指定IP后突然报错:
报错1:
Uncaught Error: Incompatibile SockJS! Main site uses: “1.6.1”, the
iframe: “1.0.0”.
报错2:
GET http://192.168.1.22:8088/ws/751/pl2birne/jsonp?c=_jp.aaxo0yy
net::ERR_ABORTED 404 (Not Found)
使用的boot版本:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.2.4.RELEASE</version>
</dependency>
使用的websocket配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {// 启用简单的消息代理,前缀为/topic的消息会发送到消息代理config.enableSimpleBroker("/topic");// 应用程序以/app为前缀的消息会路由到@MessageMapping注解的方法config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {// 注册STOMP端点,客户端将使用它连接到WebSocket服务器registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();}}
使用的前端连接socket代码:
import {Client} from '@stomp/stompjs'
import SockJS from 'sockjs-client'const createWebSocketClient = () => {let client = nullconst subscriptions = new Map()const wsBaseUrl = window.SITE_CONFIG.baseUrlconst wsEndpoint = '/ws'let messageListeners = []const connect = () => {return new Promise((resolve, reject) => {if (client && client.connected) {resolve()return}client = new Client({webSocketFactory: () => new SockJS(`${wsBaseUrl}${wsEndpoint}`),debug: (str) => console.debug('[WebSocket]', str),reconnectDelay: 5000,heartbeatIncoming: 4000,heartbeatOutgoing: 4000,onConnect: () => {console.log('[WebSocket] Connected successfully')notifyListeners('connected')resolve()},onStompError: (frame) => {console.error('[WebSocket] Connection error:', frame.headers.message)notifyListeners('error', frame.headers.message)reject(new Error(frame.headers.message || 'Connection failed'))},onDisconnect: () => {console.log('[WebSocket] Disconnected')notifyListeners('disconnected')},onWebSocketError: (error) => {console.error('[WebSocket] WebSocket error:', error)notifyListeners('error', error.message)},onWebSocketClose: (event) => {console.log('[WebSocket] WebSocket closed:', event)notifyListeners('closed', event)}})client.activate()})}const subscribe = (destination, callback) => {if (!client || !client.connected) {console.error('[WebSocket] Cannot subscribe - not connected')return null}const subscription = client.subscribe(destination, (message) => {console.log(`[WebSocket] Received message on ${destination}:`, message.body)callback(message.body)notifyListeners('message', {destination,body: message.body})})subscriptions.set(destination, subscription)return subscription}const disconnect = () => {if (client) {subscriptions.forEach(sub => sub.unsubscribe())subscriptions.clear()client.deactivate()console.log('[WebSocket] Disconnected')}}const addMessageListener = (callback) => {messageListeners.push(callback)return () => {messageListeners = messageListeners.filter(listener => listener !== callback)}}const notifyListeners = (event, data) => {messageListeners.forEach(listener => listener(event, data))}return {connect,subscribe,disconnect,addMessageListener,subscribeUsersChanged: (callback) => subscribe('/topic/xxx-topic', callback)}
}// 导出单例实例
export const webSocketClient = createWebSocketClient()
sockjs-client版本为:^1.6.1
好,如果使用以上配置时线下调试用127.0.0.1完全没问题,放到线上不是跨域就是请求/ws接口404,甚至偶尔又能请求成功,想到/ws前缀后端全放行无权限问题但就是死活报错,结果查阅大量资料后都说把setAllowedOrigins换成setAllowedOriginPatterns方法,但目前项目用的springboot版本2.2.4还没有此方法,无奈升级springboot版本到2.4.9使用setAllowedOriginPatterns方法后一下就好了。。。无语大坑,记录一下!