如何使用NSStream连接到主机名有附加路径的wss套接字?

如何使用NSStream连接到主机名有附加路径的wss套接字?

问题描述:

我正在尝试连接到wss套接字,并且主机名称如下所示:“myhostname.com/ws/v2”。 这里是我开始的连接:如何使用NSStream连接到主机名有附加路径的wss套接字?

let host = "myhostname.com/ws/v2" 

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host as CFString, 443, &readStream, &writeStream) 

inputStream = readStream!.takeRetainedValue() 
outputStream = writeStream!.takeRetainedValue() 

outputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: Stream.PropertyKey.socketSecurityLevelKey) 
inputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: Stream.PropertyKey.socketSecurityLevelKey) 

inputStream.schedule(in: .current, forMode: .commonModes) 
outputStream.schedule(in: .current, forMode: .commonModes) 

inputStream.delegate = self 
outputStream.delegate = self 

inputStream.open() 
outputStream.open() 

这失败的错误: The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 1.)

但是,如果我请从主机名的路径,所以它看起来是这样的:那么myhostname.com在我代表我得到一个事件openCompleted。然而,之后它没有回应我的消息,我认为这是因为我连接到错误的套接字,因为我删除了路径。

当主机名有附加路径时,连接到套接字的正确方法是什么?

myhostname.com/ws/v2不是主机名。它是一个(不完整的)URL(完整的URL是wss://myhostname.com/ws/v2)。主机名只是myhostname.com,该主机上的Websocket路径只是/ws/v2

WebSockets握手使用HTTP/S,所以仅用NSStream连接到主机是不够的。您必须将TCP套接字连接到host和端口,然后使用WSS协商SSL/TLS握手,然后使用HTTP请求path向WebSocket请求Upgrade,并且只有当成功的HTTP 101答复被返回,然后执行WebSocket握手。

这是很多工作要做的手动。您真的应该使用实际的WebSocket客户端库。有很多可用的。