swift使用websocket通讯,依赖库Starscream集成,并验证apple watch实现websocket可行性

这里使用webscoket,主要是使用了Starscream这个库,看图片就知道很牛X,那么干就完了。官方开源仓库地址:https://github.com/daltoniam/Starscream?tab=readme-ov-file

安装依赖库

首先,使用 Swift Package Manager 安装 Starscream。在 Xcode 中打开你的项目,选择项目文件,然后在"Swift Packages"选项卡中点击"+"按钮,添加:https://github.com/daltoniam/Starscream

创建Websocket管理器

在 SwiftUI 中使用 Starscream 创建 WebSocket 连接,并实现消息的接收和发送,可以按照以下步骤进行。Starscream 是一个流行的 WebSocket 库,能够轻松地在 iOS 和 macOS 应用中处理 WebSocket 连接:

Swift 复制代码
import Foundation
import Starscream

class WebSocketManager: ObservableObject {
    var socket: WebSocket!
    @Published var receivedMessage: String = ""

    init() {
        // 替换为你的 WebSocket 服务器地址
        var request = URLRequest(url: URL(string: "ws://192.168.1.52:8989/echo")!)
        request.timeoutInterval = 5
        socket = WebSocket(request: request)
        socket.delegate = self
        socket.connect()
    }

    func send(message: String) {
        socket.write(string: message)
    }

    func disconnect() {
        socket.disconnect()
    }
}

extension WebSocketManager: WebSocketDelegate {
    func didReceive(event: WebSocketEvent, client: WebSocketClient) {
        switch event {
        case .connected(let headers):
            print("WebSocket connected with headers: \(headers)")
        case .disconnected(let reason, let code):
            print("WebSocket disconnected with reason: \(reason), code: \(code)")
        case .text(let string):
            DispatchQueue.main.async {
                self.receivedMessage = string
            }
        case .binary(let data):
            print("Received binary data: \(data)")
        case .error(let error):
            print("WebSocket encountered an error: \(String(describing: error))")
        case .ping:
            break
        case .pong:
            break
        case .viabilityChanged:
            break
        case .reconnectSuggested:
            break
        case .cancelled:
            print("WebSocket cancelled")
        case .peerClosed:
            print("WebSocket peer closed")
        }
    }
}

创建swiftUI页面控制,实现发送和接收消息:

Swift 复制代码
//
//  StarsView.swift
//  mywatch Watch App
//
//  Created by song on 2024/6/20.
//

import SwiftUI

struct StarsView: View {
    @StateObject private var webSocketManager = WebSocketManager()
    @State private var messageToSend: String = ""

    var body: some View {
        VStack {
            Text("R: \(webSocketManager.receivedMessage)")
                .padding()

            TextField("S", text: $messageToSend)
                .padding()

            HStack {
                Button(action: {
                    webSocketManager.send(message: messageToSend)
                    messageToSend = ""
                }) {
                    Text("发")
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }

                Button(action: {
                    webSocketManager.disconnect()
                }) {
                    Text("断")
                        .padding()
                        .background(Color.red)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }
            }
        }
        .padding()
    }
}

#Preview {
    StarsView()
}

实现效果:

可以看到websocket服务器已经收到消息并打印出来了,apple watch模拟器上也收到了消息回复,

而且这个在iPhone和mac或者ipad上都是没有问题的,都可以完美支持,但是就是apple watch需要注意,apple watch真机暂不支持websocket:

但是请注意:模拟器上可以收发消息并一定说明真机上也可以的啊,所以真机测试的时候就会遇到问题,报错:NECP策略限制

nw_endpoint_flow_failed_with_error C1 192.168.1.52:8989 waiting parent-flow (unsatisfied (Path was denied by NECP policy), interface: ipsec1, ipv4, ipv6, proxy) already failing, returning

WebSocket receive error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSErrorFailingURLKey=http://192.168.1.52:8989/echo, NSErrorFailingURLStringKey=http://192.168.1.52:8989/echo, NSLocalizedDescription=The Internet connection appears to be offline.}

nw_endpoint_flow_failed_with_error C1 192.168.1.52:8989 failed parent-flow (unsatisfied (Path was denied by NECP policy), interface: ipsec1, ipv4, ipv6, proxy) already failing, returning

Connection 1: received failure notification

Connection 1: failed to connect 1:50, reason 18,446,744,073,709,551,615

Connection 1: encountered error(1:50)

那这个NECP策略是啥?看官方文档:NETWORK: NWPathMonitor non-functio... | Apple Developer Forums

相信你已经大概了解了,这个NECP策略就是网络管理器,可以控制哪些网络可以使用什么样的网络请求等,之所以在模拟器上可以连接上websocket没有问题,是因为watch os用的是mac电脑的NECP策略,所以可以成功,但是watch真机上是由于存在更低等级的网络控制,所以不成功。

那什么是 Low-Level Networking on watchOS呢?

说白了,就是watch6之前其实啥网络都不支持,但是之后就支持了http和https等,也就是还在一步一步升级中,但是请注意,虽然支持了https等,还是不支持websocket请求的。

再附上watch的网络通讯说明:关于 Apple Watch 上的蓝牙、无线局域网和蜂窝网络 - 官方 Apple 支持 (中国)

当 iPhone 在附近时,Apple Watch 会使用蓝牙,从而节省电量。

如果蓝牙无法使用,Apple Watch 会尝试使用无线局域网。例如,如果有兼容的无线局域网可用,并且 iPhone 不在蓝牙通信范围内,则 Apple Watch 会使用无线局域网。

如果蓝牙和无线局域网都不可用,并且你设置了蜂窝号码,则 Apple Watch 蜂窝网络机型可以接入蜂窝网络。

相关推荐
聪明蛋子哟11 分钟前
大模型应用“最后一公里”:从Prompt工程到MCP协议,如何实现跨系统的高可用集成?
网络·prompt
科创致远40 分钟前
ESOP 电子作业指导书 WiFi 网络应用实测报告
运维·服务器·网络
承渊政道1 小时前
Linux网络学习【从NAT与代理服务理解网络转发、探索内网穿透原理、再到认识DNS与ICMP、最后动手部署并测试内网穿透】
linux·网络·学习·内网穿透·dns·nat
最强小杰1 小时前
minimax-m3 突然报 HTTP 529 怎么办?连续重试为何更难恢复,退避时间该怎么算?
网络·网络协议·http·ai
程序员清风1 小时前
AI 编程助手的权限边界:文件、命令、密钥与人工确认
运维·服务器·网络
别讲概念2 小时前
JavaEE(5)网络原理初识
网络·java-ee·智能路由器
m0_639906942 小时前
TCP与UDP协议详解|原理、区别、粘包拆包、应用场景,面试总
网络协议·tcp/ip·udp
爱吃香菜的初学者2 小时前
十九.Linux——TCP协议(1)
linux·网络·tcp/ip
好啊好啊郝!3 小时前
计算机网络最基础知识点
服务器·网络·计算机网络
辰辰观影3 小时前
外挂字幕怎么导入播放器?2026实用教程
网络