gpt4 book ai didi

ios - StreamDelegate 在快速读取大量读数后停止接收事件

转载 作者:行者123 更新时间:2023-11-28 15:33:10 27 4
gpt4 key购买 nike

我有一个 iOS 聊天应用程序,它通过套接字连接接收消息。

当用户长时间打开应用程序并且有超过 50 条未读消息时,服务器通过套接字发送一条消息告知未读消息的数量,此时应用程序显示带有进度条的警报,然后服务器发送每一条消息。

因此,应用程序通过 StreamDelegate 方法获取每条消息stream(_ stream: Stream, handle eventCode: Stream.Event) 并更新进度条直到消息结束。

问题是,当我在某个时候有大量未读消息(大约 300 多条)时,StreamDelegate 会停止接收带有消息的事件,并且不会显示任何错误消息。

我在全局队列上调用连接方法:

DispatchQueue.global().async {
self.connect(host, port: port)
}

这是我的套接字连接代码:

    fileprivate func connect(_ host: String, port: Int) {

postStatus(.connecting)

self.host = NSString(string: host)
self.port = UInt32(port)

self.log("connect to \(host):\(port)")

var readStream : Unmanaged<CFReadStream>?
var writeStream : Unmanaged<CFWriteStream>?

CFStreamCreatePairWithSocketToHost(nil, self.host, self.port, &readStream, &writeStream)

self.inOk = false
self.outOk = false
self.inputStream = readStream!.takeRetainedValue()
self.outputStream = writeStream!.takeRetainedValue()

self.inputStream.delegate = self
self.outputStream.delegate = self


let mainThread = Thread.isMainThread;

let loop = mainThread ? RunLoop.main : RunLoop.current

self.inputStream.schedule(in: loop, forMode: RunLoopMode.defaultRunLoopMode)
self.outputStream.schedule(in: loop, forMode: RunLoopMode.defaultRunLoopMode)

self.inputStream.open()
self.outputStream.open()

self.timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(connectionTimeout), userInfo: nil, repeats: false)

if(!mainThread) {
loop.run()
}

}

在 StreamDelegate 方法中 stream(_ stream: Stream, handle eventCode: Stream.Event) 我获取消息事件并在方法 read(String) 上处理它

    case Stream.Event.hasBytesAvailable:

if let timer = timer {
timer.invalidate()
self.timer = nil
}

let json = ChatLibSwift.readMessage(self.inputStream)

do {
if StringUtils.isNotEmpty(json) {
try self.read(json)
}
} catch let ex as NSError {
LogUtils.log("ERROR: \(ex.description)")
}

break
case Stream.Event.hasSpaceAvailable:
break

读取每条消息的方法:

static func readMessage(_ inputStream: InputStream) -> String {

do {
var lenBytes = [UInt8](repeating: 0, count: 4)


inputStream.read(&lenBytes, maxLength: 4)

// header

let i32: Int = Int(UInt32.init(lenBytes[3]) | UInt32.init(lenBytes[2]) << 8 | UInt32.init(lenBytes[1]) << 16 | UInt32.init(lenBytes[0]) << 24 )

var msg = [UInt8](repeating: 0, count: (MemoryLayout<UInt8>.size * Int(i32)))

let bytesRead = inputStream.read(&msg, maxLength: Int(i32))

if bytesRead == -1 {
print("<< ChatLib ERROR -1")
return ""
}

let s = NSString(bytes: msg, length: bytesRead, encoding: String.Encoding.utf8.rawValue) as String?

if let s = s {
if bytesRead == Int(i32) {
return s
}
else {
print("Error: readMessage \(s)")
}
return s
}
return ""
} catch {

return ""
}
}

有人知道如何解决吗?

最佳答案

主要思想是在成功读取操作后强制安排流的读取:

let _preallocatedBufferSize = 64 * 1024
var _preallocatedBuffer = [UInt8](repeating: 0, count: MemoryLayout<UInt8>.size * Int(_preallocatedBufferSize))

var message : ....

func readMessage(_ inputStream: InputStream) {

if !inputStream.hasBytesAvailable || message.isCompleted {
return
}

var theBuffer : UnsafeMutablePointer<UInt8>?
var theLength : Int = 0

// try to get buffer from the stream otherwise use the preallocated buffer
if !inputStream.getBuffer(&theBuffer, length:&theLength) || nil == theBuffer
{
memset(&_preallocatedBuffer, 0, _preallocatedBufferSize)

let theReadCount = inputStream.read(&_preallocatedBuffer, maxLength:_preallocatedBufferSize)
if theReadCount > 0 {
theBuffer = _preallocatedBuffer;
theLength = theReadCount;
} else {
theBuffer = nil;
theLength = 0;
}
}

if nil != theBuffer && theLength > 0 {
_message.appendData(theBuffer, length:theLength)

self.perform(#selector(readMessage), with:inputStream, afterDelay:0.0, inModes:[RunLoopMode.defaultRunLoopMode])
}
}

关于ios - StreamDelegate 在快速读取大量读数后停止接收事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44552013/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com