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
相关产品推荐
相关产品推荐

