You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift实现Google/Android TV遥控时遇SSL握手失败问题求助

iOS SocketIO连接Google/Android TV时SSL握手失败的解决方案

问题分析

连接Google/Android TV的WebSocket服务时出现SSL握手失败,通常由以下原因导致:

  • 自签名证书未被信任:服务端使用自签名证书,但客户端配置拒绝信任该类证书
  • SocketIO配置参数冲突:同时启用forceWebsockets和forcePolling,导致协议协商异常
  • SSL验证配置缺失:未导入服务端证书公钥,无法完成证书校验
  • 未触发连接操作:仅配置监听事件,未主动发起连接请求

修正方案

1. 调整SSL配置

如果服务端使用自签名证书,需开启自签名信任;若使用公钥验证,需将服务端证书公钥导入项目并配置。

2. 移除冲突配置

forceWebsockets和forcePolling为互斥参数,根据服务端协议选择其一(Google/Android TV通常使用WebSocket协议)。

3. 添加连接触发与错误监听

主动调用连接方法,并添加错误监听以排查问题。

修正后的代码

import UIKit
import SocketIO

class ConnectViewController: UIViewController, URLSessionDelegate {
    var manager: SocketManager!
    var socket: SocketIOClient!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 初始化SSL安全配置,启用公钥验证
        let ssl = SSLSecurity(usePublicKeys: true)
        
        // 导入项目中的服务端公钥文件(示例:android_tv_public_key.pem)
        if let pubKeyPath = Bundle.main.path(forResource: "android_tv_public_key", ofType: "pem"),
           let pubKeyData = try? Data(contentsOf: URL(fileURLWithPath: pubKeyPath)) {
            ssl.addPublicKey(pubKeyData)
        }
        
        // 配置SocketManager,移除冲突参数
        manager = SocketManager(
            socketURL: URL(string: "wss://172.16.16.23:6467")!,
            config: [
                .secure(true),
                .selfSigned(true), // 服务端为自签名证书时设为true
                .security(ssl),
                .log(true),
                .sessionDelegate(self),
                .reconnects(false),
                .forceWebsockets(true)
            ]
        )
        
        socket = manager.defaultSocket
        
        // 监听连接成功事件
        socket.on(clientEvent: .connect) { _, _ in
            print("socket connected")
        }
        
        // 监听错误事件,获取详细报错信息
        socket.on(clientEvent: .error) { data, _ in
            if let error = data.first as? Error {
                print("Socket error: \(error.localizedDescription)")
            }
        }
        
        // 主动发起连接
        socket.connect()
    }
    
    // 自定义证书验证逻辑(可选,用于更灵活的信任策略)
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
              let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        let credential = URLCredential(trust: serverTrust)
        completionHandler(.useCredential, credential)
    }
}

额外说明

  • 证书处理:若无需公钥验证,可将usePublicKeys设为false,但仅在测试环境使用;生产环境建议使用合法CA签发的证书。
  • 权限配置:确保iOS项目已添加网络权限(NSAppTransportSecurity配置中允许访问目标IP,或添加NSAllowsArbitraryLoads用于测试)。

内容的提问来源于stack exchange,提问作者Samir Bagaria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:05:25