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

如何在SwiftUI项目中使用Starscream库实现WebSocket连接

把UIKit版Starscream WebSocket代码适配到SwiftUI项目的方法

1. 封装WebSocket管理类(核心步骤)

把原来的ViewController改成ObservableObject类,用来统一管理WebSocket的状态和事件,让SwiftUI视图能自动响应状态变化:

import Starscream
import Combine

class WebSocketManager: ObservableObject, WebSocketDelegate {
    @Published var isConnected: Bool = false
    var socket: WebSocket?
    var token: String = ""
    
    // 初始化并发起WebSocket连接
    func connect() {
        guard let url = URL(string: "wss://-----") else { return }
        var request = URLRequest(url: url)
        request.timeoutInterval = 5
        request.setValue("https://-----", forHTTPHeaderField: "Origin")
        
        socket = WebSocket(request: request)
        socket?.delegate = self
        socket?.connect()
    }
    
    // 主动断开连接
    func disconnect() {
        socket?.disconnect()
    }
    
    // 处理WebSocket各类事件
    func didReceive(event: WebSocketEvent, client: WebSocket) {
        switch event {
        case .connected(let headers):
            isConnected = true
            print("websocket已连接: \(headers)")
        case .disconnected(let reason, let code):
            isConnected = false
            print("websocket已断开: \(reason),错误码: \(code)")
        case .text(let string):
            if string.contains("token expiring") { 
                print("令牌即将过期")
                disconnect() 
            }
            print("收到文本: \(string)")
        case .binary(let data):
            print("收到数据: \(data.count)字节")
        case .ping(_), .pong(_), .viabilityChanged(_), .reconnectSuggested(_):
            break
        case .cancelled:
            isConnected = false
        case .error(let error):
            isConnected = false
            handleError(error)
        }
    }
    
    // 补充错误处理逻辑
    private func handleError(_ error: Error?) {
        print("WebSocket错误: \(error?.localizedDescription ?? "未知错误")")
    }
}

2. 在SwiftUI视图中调用管理类

用@StateObject创建管理类实例,监听状态变化并构建交互UI:

import SwiftUI

struct ContentView: View {
    @StateObject private var wsManager = WebSocketManager()
    
    var body: some View {
        VStack(spacing: 20) {
            // 实时显示连接状态
            Text(wsManager.isConnected ? "已连接" : "未连接")
                .font(.title)
                .foregroundColor(wsManager.isConnected ? .green : .red)
            
            // 切换连接状态的按钮
            Button(wsManager.isConnected ? "断开连接" : "连接WebSocket") {
                if wsManager.isConnected {
                    wsManager.disconnect()
                } else {
                    wsManager.connect()
                }
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
        .onAppear {
            // 视图加载完成后自动连接
            wsManager.connect()
        }
    }
}

3. 修正原代码的几个小问题

  • 原代码字符串插值语法错误:print("websocket is connected: (headers)") 要改成 print("websocket已连接: \(headers)"),否则会直接输出(headers)字符串而非实际头信息。
  • 原代码中let server = WebSocketServer()未被使用,直接删除即可。
  • 补充了原代码缺失的handleError方法实现,避免编译报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:41:05