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# 编写的,但它是该主题的一个很好的参考。
我正在创建基于 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# 编写的,但它是该主题的一个很好的参考。