PublishSubject 与 CocoaAsyncSocket 的正确用法

Correct usage of PublishSubject with CocoaAsyncSocket

我正在创建基于 CocoaAsyncSocket 和 STOMP 协议的简单消息传递应用程序。所以我创建了 main class,它使用 PublishSubject,因此订阅者可以观察传入的 STOMP 帧,如下所示:

class StompStream: NSObject {
//MARK: - Public
     var inputFrame = PublishSubject<StompFrame>()

//MARK: - Private
    fileprivate var socket: GCDAsyncSocket!
    ...
    ...
    fileprivate func parse(withData data: Data) {
        let string = String(data: data, encoding: .utf8)
        do {
            let frame = try StompFrame(text: string)
            self.inputFrame.on(.next(frame))
        } catch {
            self.inputFrame.on(.error(error))
        }
     }
 }
//MARK: - GCDAsyncSocketDelegate methods
extension StompStream: GCDAsyncSocketDelegate {
    ...
    ...
    func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
        self.parse(withData: data)
    }
}

所以,其他想要阅读 inputFrame 的人,只需这样做:

fileprivate func subscribeToEvents() {
    self.stompStream.inputFrame
        .observeOn(SerialDispatchQueueScheduler(queue: Queues().stompQueue, internalSerialQueueName: "stomp"))
        .subscribe( onNext: { inputFrame in
            //do some stuff
        }).addDisposableTo(self.disposeBag)
}

我是 RxSwift 的新手,我读到,如果我们只想读取事件,最好使用 Observable<StompFrame>,但是使用 PublishSubject 我可以像这样初始化它 - PublishSubject<StompFrame>(),并且使用 Observable<StompFrame> 我无法理解如何做这样的事情,如果不创建一些 func,我将 return Observable.create { },所以每次如果有人会想要接收事件,它会创建另一个 Observable<StompFrame>,但是 PublishSubject 它只是一个。 感谢您帮助我解释这个 Rx 的东西 :)

因为代码是从命令式世界到反应式世界的桥梁,所以在这里使用 PublishSubject 幕后是有意义的.

一个好的做法是将此主题设为私有并且只向外部用户公开 Observable

class StompStream: NSObject {
    var inputFrame: Observable<StompFrame> { 
        return inputFrameSubject.asObservable() 
    }

    private let inputFrameSubject = PublishSubject<StompFrame>()

    // ...
}

当不确定是否使用主题时,我总是参考 this post。虽然是为 C# 编写的,但它是该主题的一个很好的参考。