Incompatibile SockJS! Main site uses:.... sockjs报错

先上图:

sockjs stomp springboot-websocket

公司的项目,经测试,直连没有问题,但只要放到服务器上,除了第一次连接,用户只要刷新页面,触发重连就开始报错。

nginx的socket已经配置过了,

在前端报错的同时,后端也会报断开连接(不知道是不是心跳包报的错)

错误信息如下:

因为socket和项目是同端口,所以没有办法远程调试。。。

下面是我的配置信息

nginx:

nginx.conf:

user  nginx;

worker_processes 1;

error_log /var/log/nginx/error.log warn;

pid /var/run/nginx.pid;

events {

worker_connections 1024;

}

http {

include /etc/nginx/mime.types;

default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;

#tcp_nopush on;

keepalive_timeout 65;

gzip on;

map $http_upgrade $connection_upgrade {

default upgrade;

'' close;

}

include /etc/nginx/conf.d/default/default.conf; #先去加载 default.conf 保证直接内网访问ip时 映射到default.conf内

include /etc/nginx/conf.d/*.conf;

}

xxx.xxxx.xxx.conf:

server {

listen 80;

server_name xxx.xxxx.xxx;

location / {

#add_header 'Access-Control-Allow-Origin' '*';

proxy_http_version 1.1;

proxy_pass http://192.168.1.23:27081;

proxy_set_header Host $host;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

proxy_set_header X-Forwarded-For $remote_addr;

proxy_set_header X-Real-Ip $proxy_add_x_forwarded_for;

proxy_connect_timeout 60;

proxy_read_timeout 600;

proxy_send_timeout 600;

}

}

java

@Configuration

@EnableWebSocketMessageBroker

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Autowired

TokenStore tokenStore;

public static final String Topic = "ws-topic";

public static final String Queue = "ws-queue";

public static final String HandUrl = "/endpoint";

private static long HEART_BEAT = 5000;

@Override

public void registerStompEndpoints(StompEndpointRegistry registry) {

//注册STOMP的endpoint,使用SockJS

registry.addEndpoint(HandUrl)

.setAllowedOrigins("*")

.addInterceptors(new ConnectionInterceptor())

.withSockJS()

.setClientLibraryUrl("https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js") // 无效

.setMessageCodec(new FastjsonSockJsMessageCodec());//使用fastjson序列化

}

@Override

public void configureMessageBroker(MessageBrokerRegistry registry) {

//心跳任务

ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler();

te.setPoolSize(1);

te.setThreadNamePrefix("wss-heartbeat-thread-");

te.initialize();

//注册消息代理地址

registry.enableSimpleBroker(String.format("/%s/", Topic), String.format("/%s/", Queue))

.setHeartbeatValue(new long[]{HEART_BEAT, HEART_BEAT})

.setTaskScheduler(te);

registry.setApplicationDestinationPrefixes("/ws/ws-bmw"); // 广播消息订阅前缀

registry.setUserDestinationPrefix("/ws/ws-user"); // 点对点消息订阅前缀

// registry.setPreservePublishOrder(true); // 保证推送顺序,但会增加性能开销

}

// 拦截替换 Principal

@Override

public void configureClientInboundChannel(ChannelRegistration registration) {

registration.interceptors(new ChannelInterceptor() {

@Override

public Message<?> preSend(@NotNull Message<?> message, MessageChannel channel) {

StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

if (accessor==null) throw new BadCredentialsException("未授权");

// 判断是否断开连接

//1、判断是否首次连接

if (StompCommand.CONNECT.equals(accessor.getCommand())){

//2、拿到token,获取授权信息

List<String> authorization = accessor.getNativeHeader("Authorization");

if (authorization==null || authorization.size()==0) throw new BadCredentialsException("未授权");

String token = authorization.stream().findFirst().orElse(null);

if (StringUtils.isEmpty(token)) throw new BadCredentialsException("未授权");

OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);

if (oAuth2Authentication==null) throw new BadCredentialsException("未授权");

UserDetails userDetails = (UserDetails)oAuth2Authentication.getUserAuthentication().getPrincipal();

if (userDetails==null) throw new BadCredentialsException("未授权");

SocketUserInfo socketUserInfo = new SocketUserInfo();

BeanUtils.copyProperties(userDetails, socketUserInfo);

accessor.setUser(socketUserInfo);

return message;

}

//不是首次连接,已经登陆成功

return message;

}

});

}

}

Vue:

socket.js:

import SockJS from 'sockjs-client';

import Stomp from 'stompjs';

import { getToken } from "./util";

import config from '@/config/config'

const baseURL = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro;

class Socket {

constructor(baseUrl = baseURL){

this.stompClient = {};

this.baseUrl = baseUrl//baseUrl;

this.tryCount = 10; //重连尝试次数, 小于1为不重连

this.tryDuration = 1000; //重连时间间隔 单位ms

this.handUrl = "/endpoint"; // 握手连接

};

handler(data){}; // 该方法在组件内被重写

connectionError(err, userId){

console.error("握手出错", err);

this.tryOpen(userId);

}

connection(userId) {

// 发起连接

this.stompClient.connect(this.getHeaders(), () => { this.connectionSuccess(userId); } , err =>{ this.connectionError(err, userId); });

};

tryOpen(userId, tempCount = this.tryCount) {

let tryTask = (tempCount)=>{

if(tempCount<1) return;

if(!this.stompClient || this.stompClient=={} || !this.stompClient.connected ) {

console.warn(`尝试重连: ${this.baseUrl}${this.handUrl}`);

this.connection(userId);

setTimeout(()=>{

tryTask(tempCount-1);

}, this.tryDuration);

}

}

tryTask(tempCount);

};

disconnect() {

if (this.stompClient) {

this.stompClient.disconnect();

}

};

init(userId){

if(!userId) return;

// 建立连接对象

let socket = new SockJS(`${this.baseUrl}${this.handUrl}`);

// 获取STOMP子协议的客户端对象

this.stompClient = Stomp.over(socket);

// 日志

this.stompClient.debug = process.env.NODE_ENV === 'development' ? str=>{

console.log(str)

}: str=>{};

// 心跳包

this.stompClient.heartbeat.outgoing = 10000; // 非负整数 发送心跳的间隔(PING) 单位ms 0表示不发送

this.stompClient.heartbeat.incoming = 10000; // 非负整数 接收心跳的最小时间间隔(PONG) 单位ms 0表示不想接收

this.stompClient.ws.onclose = () => {

this.tryOpen(userId);

}

this.stompClient.ws.onerror = () => {

this.tryOpen(userId);

}

console.log(this.stompClient.ws)

this.connection(userId);

};

// 连接成功

connectionSuccess(userId){

//订阅 点对点接口

this.stompClient.subscribe('/ws/ws-user/ws-queue/getResponse', msg => {

this.handler(msg); //处理消息

}, this.getHeaders());

this.stompClient.send(`/ws/ws-bmw/online`, this.getHeaders(), JSON.stringify({id:userId}))

// this.stompClient.send("/ws-bmw/ws-user/receive",

// headers,

// JSON.stringify({a:"123"}),

// ) //用户加入接口

}

getHeaders(){

return {

Authorization: getToken()

}

}

destroyed () {

this.disconnect();

}

}

export default new Socket(baseURL)

服务器环境

弄这个东西弄了一周了,请教一个解决办法,谢谢🙏

回答

image.png

兼容性问题

以上是 Incompatibile SockJS! Main site uses:.... sockjs报错 的全部内容, 来源链接: utcz.com/a/23619.html

回到顶部