sockjsstomp·

Sockjs + stompjs 与 springboot-websocket报跨域问题

1412733862

1412733862

460 0

作者,我运行你代码时,为啥会报跨域问题,该怎么解决啊 前端

import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import apiConfig from '~/config/api.config'
import Vue from 'vue'
export default  ({app},inject) =>{
  const sockjs = {
    socket: null,
    stompClient: null,
    headers: null,
    successCallback() {
      debugger
      let _ts = this;
      _ts.stompClient.subscribe(`/user/${_ts.headers.id}/message`, (msg) => {
        let message = JSON.parse(msg.body);
        console.log(message.dataType)
        switch (message.dataType) {
          case 0:
            console.log(message.content)
            break;
          case 1:
            console.log(message.to)
            break;
          default:
            console.log(message)
        }
      }, _ts.headers);
      _ts.stompClient.subscribe('/topic/greening', (msg) => {
        console.log('pub', JSON.parse(msg.body));
      }, _ts.headers);
    },
    initSocket: function (user) {
      let _ts = this;
      _ts.socket = new SockJS(apiConfig.SOCKET);
      _ts.stompClient = Stomp.over(_ts.socket);
      let headers = {
        id: user.account
      }
      _ts.headers = headers;
      _ts.stompClient.connect(_ts.headers, () => {
        _ts.successCallback();
      }, (err) => {
        console.log(err)
        _ts.reconnect(apiConfig.SOCKET, _ts.successCallback)
      });
    },
    // 断开重连使用定时器定时连接服务器
    reconnect(socketUrl, successCallback) {
      console.info('in reconnect function')
      let connected = false
      let _ts = this
      const reconInv = setInterval(() => {
        console.info('in interval' + Math.random())
        _ts.socket = new SockJS(socketUrl)
        _ts.stompClient = Stomp.over(this.socket)
        _ts.stompClient.connect({}, (frame) => {
          console.info('reconnected success')
          // 连接成功,清除定时器
          clearInterval(reconInv)
          connected = true
          successCallback()
        }, () => {
          console.info('reconnect failed')
          console.info('connected:' + connected)
          if (connected) {
            console.info('connect .... what?')
          }
        })
      }, 2000)
    },
    sendMessage: function (message) {
      this.stompClient.send('/message', {}, JSON.stringify(message))
    },
    sendTopicMessage: function(message) {
      this.stompClient.send('/sendMessage', {}, JSON.stringify(message));
    }
  }
  inject('sockjs',sockjs);
}

后端

package com.rymcu.forest.web.api.common;

import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.authz.annotation.RequiresPermissions;
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.SendToUser;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

/**
 * @author ronger
 */
@Controller
@RequiresPermissions(value = "user")
public class WebSocketController {

    @Resource
    private SimpMessagingTemplate template;

    @MessageMapping("/sendMessage")
    @SendTo("/topic/greening")
    public void sendMessage(JSONObject message, StompHeaderAccessor headerAccessor) {
        this.template.convertAndSend("/topic/greening", message);
    }

    @MessageMapping("/message")
    @SendToUser("/message")
    public void message(JSONObject message, StompHeaderAccessor headerAccessor) {
        this.template.convertAndSendToUser(message.getString("to"), "/message", message);
    }
}

后端配置```
package com.rymcu.forest.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;

/**
 * @author ronger
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
    /**
     * 注册stomp端点
     *
     * @param registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 允许使用socketJs方式访问 即可通过http://IP:PORT/ws来和服务端websocket连接
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
        registry.addEndpoint("/wss").setAllowedOrigins("*").withSockJS();
    }

    /**
     * 配置信息代理
     *
     * @param registry
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {

        // 订阅Broker名称 user点对点 topic广播即群发
        registry.enableSimpleBroker("/topic", "/user");
        // 全局(客户端)使用的消息前缀
        registry.setApplicationDestinationPrefixes("/app");
        // 点对点使用的前缀 无需配置 默认/user
        registry.setUserDestinationPrefix("/user");
    }
}

错误 Access to XMLHttpRequest at 'http://localhost:8099/forest/ws/info?t=1718967139026' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人