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

相关推荐
安步当歌1 小时前
【WebRTC】视频发送链路中类的简单分析(下)
网络·音视频·webrtc·视频编解码·video-codec
米饭是菜qy2 小时前
TCP 三次握手意义及为什么是三次握手
服务器·网络·tcp/ip
yaoxin5211232 小时前
第十九章 TCP 客户端 服务器通信 - 数据包模式
服务器·网络·tcp/ip
鹿鸣天涯2 小时前
‌华为交换机在Spine-Leaf架构中的使用场景
运维·服务器·网络
星海幻影2 小时前
网络基础-超文本协议与内外网划分(超长版)
服务器·网络·安全
WeeJot嵌入式2 小时前
网络百问百答(一)
网络
湖南罗泽南2 小时前
p2p网络介绍
网络·网络协议·p2p
heilai42 小时前
workerman的安装与使用
c++·websocket·http·php·phpstorm·visual studio code
有梦想的咕噜2 小时前
Secure Shell(SSH) 是一种网络协议
运维·网络协议·ssh
IPdodo全球网络3 小时前
解析“ChatGPT网络错误”:从网络专线到IP地址的根源与解决方案
网络·tcp/ip·chatgpt