You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic iOS项目SocketJS+Stomp连接失败问题求助

Ionic项目SocketJS+Stomp在iOS模拟器无法连接问题排查

问题描述

SocketJS+Stomp服务在浏览器中可正常运行,但Xcode的iOS虚拟机中无法建立连接,报错信息:

[log] - Opening Web Socket...
[log] - Whoops! Lost connection to http://44.211.141.255:8080/sba-websocket

关联代码

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import * as SockJS from 'sockjs-client';
import * as Stomp from 'stompjs';

@Injectable({
    providedIn: 'root',
})
export class StompService {
    private connecting: boolean = false;
    private topicQueue: any[] = [];

    options = {
        timeout: 10000, // 设置超时时间为 10 秒
      };
    socket = new SockJS('http://44.211.141.255:8080/sba-websocket',undefined,this.options);
    stompClient = Stomp.over(this.socket);
    
    subscribe(topic: string, callback?: any): void {
        // If stomp client is currently connecting add the topic to the queue
        if (this.connecting) {
            console.log("ing");
            this.topicQueue.push({
                topic,
                callback
            });
            return;
        }
        console.log("2");
        const connected: boolean = this.stompClient.connected;
        if (connected) {
            // Once we are connected set connecting flag to false
            console.log("ed");
            this.connecting = false;
            this.subscribeToTopic(topic, callback);
            return;
        }

        // If stomp client is not connected connect and subscribe to topic
        this.connecting = true;
        this.stompClient.connect({}, (): any => {
            this.subscribeToTopic(topic, callback);

            // Once we are connected loop the queue and subscribe to remaining topics from it
            this.topicQueue.forEach((item:any) => {
                this.subscribeToTopic(item.topic, item.callback);
            })

            // Once done empty the queue
            this.topicQueue = [];
        });
    }

    private subscribeToTopic(topic: string, callback?: any): void {
        this.stompClient.subscribe(topic, (response?:string): any => {
            console.log(response);
            callback(response);
        });
    }
}

排查与解决方法

1. 处理iOS ATS限制

iOS默认拦截非HTTPS网络请求,当前使用http://协议需修改项目Info.plist:

  • 打开Xcode,找到项目的Info.plist文件
  • 添加App Transport Security Settings字典,新增Allow Arbitrary Loads并设为YES;若要更安全,可添加Exception Domains子字典,将44.211.141.255作为子项,开启Allows Arbitrary Loads in Web Content和NSIncludesSubdomains为YES

2. 强制SockJS使用websocket传输

iOS模拟器WebView环境与浏览器存在差异,强制指定传输方式可规避兼容问题:

const socket = new SockJS('http://44.211.141.255:8080/sba-websocket', undefined, {
  timeout: 10000,
  transports: ['websocket'] // 强制使用websocket协议
});

同时确保sockjs-client版本稳定,建议使用1.5.2这类经过验证的版本。

3. 添加错误监听与调整连接时机

当前代码未处理连接失败场景,需补充错误回调定位问题:

this.stompClient.connect({}, () => {
    // 成功连接逻辑
}, (error) => {
    console.error('连接失败详情:', error);
    this.connecting = false;
    // 可根据需求添加重连逻辑
});

避免在服务初始化时直接创建Socket实例,建议等待Ionic平台就绪后再初始化:

import { Platform } from '@ionic/angular';

constructor(private platform: Platform) {}

async subscribe(topic: string, callback?: any) {
    await this.platform.ready();
    // 后续连接逻辑
}

4. 验证服务器端配置

  • 确保服务器SockJS端点允许跨域请求,需包含iOS模拟器的来源(如capacitor://localhost、ionic://localhost)
  • 检查服务器防火墙/安全组是否开放8080端口,允许模拟器所在网络访问

5. 确认模拟器网络连通性

用iOS模拟器的Safari访问http://44.211.141.255:8080/sba-websocket,若能正常返回页面则网络连通;若无法访问,需排查模拟器网络设置或服务器可达性。

内容的提问来源于stack exchange,提问作者Yida Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:15:33