很奇怪,但是我找不到任何信息:如果我在iOS上向WebSocket流写入[大]消息,并且执行返回到我的代码,该消息是否已经发送或以某种方式进行了缓冲?
我正在使用Starscream库,但它仅使用CFStream-s。
答案 0 :(得分:1)
看看提到的source code for the Starscream library,该库将send操作附加到NSOperation队列:
private func dequeueWrite(..) {
...
writeQueue.addOperation(operation)
}
,然后立即返回。
因此,当其中一个send方法返回时,例如:
open func write(data: Data, completion: (() -> ())? = nil)
该消息尚未发送。
但是正如您所看到的,您可以将完成块传递给此方法,当将整个消息写入基础输出流时将调用该完成块。请注意,这并不能告诉您有关消息是实际上已经在网络上发送,还是发件人是否已成功接收。
要知道发件人是否已成功接收并处理了消息,您需要等待响应消息-这是您需要在应用协议中定义的内容。
在生产环境中使用Starscream库之前,您可能需要报告/修复其中的一些问题。在查看发送机制时,我注意到,如果WebSocket.swift line 1254上的OutputStream缓冲区已满,则库将尝试在繁忙循环中发送缓冲区的其余部分,而不是等待hasSpaceAvailable
事件。如果您发送一条大消息,这可能会浪费很多CPU周期。
同样,看起来stream.write
返回0(表示输出缓冲区已满)的情况被错误地视为错误。
答案 1 :(得分:0)
可能使用
func CFWriteStreamWrite(_ stream: CFWriteStream!,
_ buffer: UnsafePointer<UInt8>!,
_ bufferLength: CFIndex) -> CFIndex
write调用返回“成功写入的字节数,如果流已满(对于定长流),则为0;如果流未打开或发生错误,则为-1”。 >
是的,它们被缓冲了。但是我认为这是唯一的选择,因为每个套接字都有一个最大缓冲区zsize,所以写函数需要有缓冲区。