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

相关推荐
Python私教1 小时前
FastAPI 与 JWT 身份验证:保护你的 API
网络·fastapi
Orlando cron4 小时前
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
网络·tcp/ip·kubernetes
KKKlucifer7 小时前
加密通信 + 行为分析:运营商行业安全防御体系重构
网络·安全·重构
achene_ql9 小时前
select、poll、epoll 与 Reactor 模式
linux·服务器·网络·c++
黎相思10 小时前
应用层自定义协议与序列化
运维·服务器·网络
邪恶的贝利亚10 小时前
实现p2p的webrtc-srs版本
网络协议·webrtc·p2p
Lightning-py11 小时前
Linux命令cat /proc/net/snmp查看网络协议层面统计信息
网络·网络协议·tcp/ip
2501_9151063212 小时前
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
websocket·网络协议·tcp/ip·http·网络安全·https·udp
wo32586614512 小时前
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
开发语言·网络·php
光路科技13 小时前
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
服务器·网络·重构