【问题标题】:IOS UI freeze during socket connection在套接字连接期间 IOS UI 冻结
【发布时间】:2018-06-05 11:51:28
【问题描述】:

我对流或套接字连接不太了解,但似乎没有其他东西可以满足我的需要。我正在尝试建立一个简单的连接,让我可以监控打开的连接并在收到输入时读取该输入。

连接工作正常,但用户界面在连接设置期间冻结。我不确定如何将其推送到后台,以免干扰 UI。

下面的套接字类

import Foundation

protocol SocketDelegate {
  func hasBytes(stream: Stream)
  func opened(stream: Stream)
  func error(stream: Stream)
  func closed(stream: Stream)
  func other(stream: Stream)
}

class Socket: NSObject, StreamDelegate {

  fileprivate var hostname: String
  fileprivate var port: Int

  fileprivate var delegate: SocketDelegate?

  fileprivate var istreamopen: Bool
  fileprivate var ostreamopen: Bool

  fileprivate var istream : InputStream?
  fileprivate var ostream : OutputStream?

  init(hostname: String, port: Int) {

    self.hostname = hostname
    self.port = port
    self.istreamopen = false
    self.ostreamopen = false

    Stream.getStreamsToHost(withName: self.hostname, port: self.port, inputStream: &self.istream, outputStream: &self.ostream)


    self.istream!.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
    self.ostream!.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)

  }


  func getInputStream() -> InputStream {
    return istream!
  }

  func getOutputStream() -> OutputStream {
    return ostream!
  }

  func Connect() -> Void {

    self.istream?.delegate = self
    self.ostream?.delegate = self

    istream!.open()
    ostream!.open()
  }

  func DisConnect() -> Void {
    istream!.close()
    ostream!.close()
    istreamopen = false
    ostreamopen = false
  }

  func write(bytes: [UInt8]) {
    ostream?.write(bytes, maxLength: (bytes).count)
  }

  func write(string: String) {
    ostream?.write([UInt8](string.utf8), maxLength: ([UInt8](string.utf8)).count)
  }

  func read(bufferSize: Int) -> String {
    var output = String()
    var buffer = [UInt8](repeating: 0, count: bufferSize)
    //while (self.istream?.hasBytesAvailable)! {
      //print("HELLO")
      let bytesRead: Int = self.istream!.read(&buffer, maxLength: buffer.count)
      if bytesRead >= 0 {
        output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: String.Encoding.ascii.rawValue)! as String
      } else {
        output = "# Stream read() error"
      }
      //print(output)
    //}
    return output
  }


  func setDelegate(delegate: SocketDelegate) -> Void {
    self.delegate = delegate
  }

  func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    //print("\(aStream) Stream!")
    switch eventCode {
    case Stream.Event.hasBytesAvailable:
      delegate?.hasBytes(stream: aStream)
      break;
    case Stream.Event.errorOccurred:
      //print("Stream error occurred: %@",aStream.streamError?.localizedDescription ?? "ERROR")
      delegate?.error(stream: aStream)
    case Stream.Event.openCompleted:
      //print("\(aStream)  --  \(self.istream)  --  \(self.ostream)")
      if (aStream == self.istream) {
        self.istreamopen = true
        //print("\(self.istream) Open")
      } else if (aStream === self.ostream) {
        self.ostreamopen = true
        //print("\(self.ostream) Open")
      }
      delegate?.opened(stream: aStream)
      break
    case Stream.Event.endEncountered:
      //print("Stream ended")
      if (aStream === self.istream) {
        self.istreamopen = false
      } else if (aStream === self.ostream) {
        self.ostreamopen = false
      }
      delegate?.closed(stream: aStream)
      break
    default:
      delegate?.other(stream: aStream)
      break
    }
  }

  func isConnected() -> Bool {
    return (istreamopen && ostreamopen)
  }


}

【问题讨论】:

  • 在高层次上,我会将 getStreamsToHost 从 init 中拉出来,并将其放入一个名为“start”或其他的新方法中。该方法应该使用转义闭包以使其异步,然后在完成后通过闭包/块回调给您。

标签: ios sockets stream


【解决方案1】:

我似乎不是连接失败了。这是 SSL 协商期间的初始写入。我将写入命令包装在 DispatchQueue 中,它似乎已经解决了这个问题。

  func write(bytes: [UInt8]) {
    DispatchQueue.global(qos: .background).async {
      self.ostream?.write(bytes, maxLength: (bytes).count)
    }
  }

  func write(string: String) {
    DispatchQueue.global(qos: .background).async {
      self.ostream?.write([UInt8](string.utf8), maxLength: ([UInt8](string.utf8)).count)
    }
  }

【讨论】:

    【解决方案2】:

    我也试过了,它有很多像你现在面临的问题,所以尝试使用这个库,它会为你完成繁重的工作

    socket.io-client-swift

    【讨论】:

    • 不确定如何使用 socket.io 这是我测试的第一个,它与我连接的 REST 服务器不合作。我试图修改源代码但很短。它似乎也期待一个特定的端点。我可能看错了,但它似乎只想连接到 socket.io 服务器。
    猜你喜欢
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多