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 蜂窝网络机型可以接入蜂窝网络。

相关推荐
mounter6251 小时前
绕过主机:通过 Devmem TCP 运行 RDMA 应用
网络·网络协议·tcp/ip·rdma·devmem
我星期八休息2 小时前
网络编程—网络层
开发语言·前端·网络·人工智能·智能路由器
科力锐品牌君3 小时前
行业龙头|科力锐全链路防勒索 + 多中心容灾方案,构筑河南翔宇医疗业务安全闭环!
网络·数据库·分布式·安全·数据安全·备份
2401_868534784 小时前
C语言与C++在基础语法上的区别
网络·网络协议
黄俊懿5 小时前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第三节:CDN扩展-多地址直连
网络·计算机网络·架构·系统架构·cdn·dns·架构设计
Dr.kangder5 小时前
嵌入式总线设备解析——TTE总线应用与实践
开发语言·网络·算法·嵌入式·多任务·同步机制
数据知道6 小时前
IDOR 不安全的直接对象引用:API 越权实战检测
java·开发语言·网络·安全·网络安全
WHS-_-20227 小时前
基于网络感知自适应树与辅助路由加速地理分布式机器学习
网络·分布式·机器学习
果果燕7 小时前
实习笔记(二)NFS 嵌套挂载问题完整复盘
linux·服务器·网络
g3voip8 小时前
工业防爆电话选型指南:防爆参数、SIP接入与调度系统集成
linux·服务器·网络·信息与通信·ip·pbx