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

相关推荐
灵韵设计3 分钟前
学习笔记——动态路由——OSPF(工作原理)
网络
陪我养猪吧4 分钟前
网络“ping不通”,如何排查和解决呢?
网络
Ljubim.te1 小时前
计算机网络网络层复习题2
网络·计算机网络·智能路由器
落子摘星1 小时前
netlink通信——读取路由表获取通信网卡IP
网络·网络协议·tcp/ip·netlink
IT 青年2 小时前
网安小贴士(3)网安协议
网络·网安协议·网安小贴士
法号:吃肉5 小时前
求推荐几款http可视化调试工具?
网络·网络协议·http
Canon_YK10 小时前
安全隔离上网的有效途径:沙箱
服务器·网络·安全·web安全·网络安全
光路科技10 小时前
VLAN的工作原理、划分方式、配置示例
网络·智能路由器·php
CXDNW10 小时前
全面了解机器学习
网络·人工智能·深度学习·机器学习·计算机·机器学习算法·模型训练
不如小布.10 小时前
Linux:网络基础1
linux·运维·网络