Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用rxSwift进行长轮询_Ios_Swift_Long Polling_Rx Swift - Fatal编程技术网

Ios 使用rxSwift进行长轮询

Ios 使用rxSwift进行长轮询,ios,swift,long-polling,rx-swift,Ios,Swift,Long Polling,Rx Swift,我正在研究rxSwift,我想为c longpolling服务器与该服务的交互提供服务,模拟永久连接。是我写的,但在我看来,这个决定不应该做得更好吗?是否有可能以某种方式重复可观察到的结果,而不考虑错误,这取决于longpoll服务器的响应 任何人都可以分享解决方案吗?还是帮我提建议?如何更好地组织?我希望看到更好的解决方案,因为我刚刚开始研究rxswift class LongPollingService { public var messageReciver: PublishSub

我正在研究rxSwift,我想为c longpolling服务器与该服务的交互提供服务,模拟永久连接。是我写的,但在我看来,这个决定不应该做得更好吗?是否有可能以某种方式重复可观察到的结果,而不考虑错误,这取决于longpoll服务器的响应

任何人都可以分享解决方案吗?还是帮我提建议?如何更好地组织?我希望看到更好的解决方案,因为我刚刚开始研究rxswift

class LongPollingService {

    public var messageReciver: PublishSubject<EventProtocol> = PublishSubject<EventProtocol>()

    private let transport = DefaultTransport()

    private let disposeBag = DisposeBag()

    private var currentRequestInfo = Variable<LongpollingServerInfo?>(nil)

    private var currentRequestDisposable: Disposable?

    private var currentLongpollingConnection: Disposable? // Subsribee for request server info

    private var eventListener : Disposable?

    private var currentReqursiveConnection: Disposable? // Subscriber for event listener from longpoll server

    func startObservableEvents() {
        getServerConnection()
        subscribeServerInfo()
        //testing listen events
        eventListener = messageReciver.showMessagesInDebugMode().subscribe()
        eventListener?.addDisposableTo(disposeBag)
    }

    func disconnect() {
        currentRequestDisposable?.dispose()
        currentLongpollingConnection?.dispose()
        currentReqursiveConnection?.dispose()
    }

    private func subscribeServerInfo() {
        currentLongpollingConnection = currentRequestInfo
            .asObservable()
            .filter({$0 != nil})
            .subscribe(onNext: { [weak self] (info) in
                guard let sSelf = self else { return }
                sSelf.subscribeToEvents(timeStamp: info!.ts)
            })
        currentLongpollingConnection?.addDisposableTo(disposeBag)
    }

    private func subscribeToEvents(timeStamp: TimeInterval) {
        if let serverInfo = currentRequestInfo.value {
            currentReqursiveConnection?.dispose()
            currentReqursiveConnection = getEventsFromLongpollServer(serverInfo: serverInfo, with: timeStamp)
                .flatMap(parseUpdates)
                .flatMap(reciveEvents)
                .showErrorsSwiftMessagesInDebugMode()
                .subscribe(onNext: { [weak self] updates in
                    guard let sSelf = self else { return }
                    sSelf.subscribeToEvents(timeStamp: updates)
                },
                onError: { [weak self] error in
                    guard let sSelf = self else { return }
                        if let error = error as? LongPollError {
                            switch error {
                            case .olderHistory(let ts): sSelf.subscribeToEvents(timeStamp: ts)
                            default: sSelf.getServerConnection()
                            }
                        }
                })
            currentReqursiveConnection?.addDisposableTo(disposeBag)
        }
    }

    private func getServerConnection() {
        //get longpolling server info for connection.
        currentRequestDisposable = getLongpollServerInfo()
            .subscribe(onNext: {[weak self] info in
                guard let sSelf = self else { return }
                sSelf.currentRequestInfo.value = info
            })
        currentRequestDisposable?.addDisposableTo(disposeBag)
    }

    private func parseUpdates(json: Any) throws -> Observable<LongPollingUpdates> {
        let response = try Mapper<LongPollingUpdates>().map(JSONObject: json)
        return .just(response)
    }

    private func reciveEvents(updates:LongPollingUpdates) throws -> Observable<TimeInterval> {
        if let errors = updates.failed {
            throw parseErrors(errors: errors)
        }
        if let events = updates.updates {
            parseUpdates(updates: events)
        }
        return Observable.just(updates.timeStamp!)
    }

    private func parseUpdates(updates: [[Any]]) {
        updates.forEach { (array) in
            let firstElementInUpdate = array.first
            if let update = firstElementInUpdate as? Int {
                switch update {
                case 1: break
                case 2: break
                case 3: break
                case 4: messageReciver.onNext(NewMessage(array: array))
                default: break
                }
            }
        }
    }

    private func parseErrors(errors: [String: Any]) -> LongPollError {
        if let error = errors["failed"] as? Int {
            switch error {
            case 1:
                guard let ts = errors["ts"] as? TimeInterval else { return .unkownError }
                return .olderHistory(ts: ts)
            case 2: return .needNewkey
            case 3: return .needCaseAndTs
            case 4: return .unkownVersion
            default:
                return .unkownError
            }
        }
        return .unkownError
    }

    private func getEventsFromLongpollServer(serverInfo: LongpollingServerInfo, with ts: TimeInterval) -> Observable<Any> {
        let url = buildLongPollingServerRoute(from: serverInfo, with: ts)
        let request = buldLongPollRequst(route: url)
        let requestConvert = try? URLEncoding.default.encode(request!, with: nil)
        return transport.makeRequest(request: requestConvert!)
    }

    private func getEventsFromLongpollServer(serverInfo: LongpollingServerInfo) -> Observable<Any> {
        let url = buildLongPollingServerRoute(from: serverInfo)
        let request = buldLongPollRequst(route: url)
        let requestConvert = try? URLEncoding.default.encode(request!, with: nil)
        return transport.makeRequest(request: requestConvert!)
    }

    private func getLongpollServerInfo() -> Observable<LongpollingServerInfo> {
        let request = MessageRouter.getLongpollServer(useSsl: false, needPts: false)
        return transport.makeModel(request: request)
    }

}
class LongPollingService{
public var messagereceiver:PublishSubject=PublishSubject()
private let transport=DefaultTransport()
私有出租dispebag=dispebag()
私有变量currentRequestInfo=变量(nil)
私人var currentRequestDispossible:一次性?
私有var currentLongpollingConnection:一次性?//请求服务器信息的子订阅
私有var eventListener:一次性?
private var currentReqursiveConnection:一次性?//longpoll服务器事件侦听器的订阅服务器
func startObservableEvents(){
getServerConnection()
subscribeServerInfo()
//测试监听事件
eventListener=messageReciver.showMessagesInDebugMode().subscribe()
eventListener?.addDisposableTo(disposeBag)
}
func disconnect(){
CurrentRequestDispose?.dispose()
currentLongpollingConnection?.dispose()
currentReqursiveConnection?.dispose()的
}
私有函数subscribeServerInfo(){
currentLongpollingConnection=currentRequestInfo
.asObservable()
.filter({$0!=nil})
.subscribe(onNext:{[weak self](信息)在中)
guard let sSelf=self-else{return}
self.subscribeToEvents(时间戳:info!.ts)
})
currentLongpollingConnection?.addDisposableTo(disposeBag)
}
private func subscribeToEvents(时间戳:时间间隔){
如果让serverInfo=currentRequestInfo.value{
currentReqursiveConnection?.dispose()的
currentReqursiveConnection=getEventsFromLongpollServer(serverInfo:serverInfo,带:时间戳)
.flatMap(解析更新)
.flatMap(reciveEvents)
.batherRorsSwiftMessagesInDebugMode()
.subscribe(onNext:{[weak self]更新在中)
guard let sSelf=self-else{return}
sSelf.subscribeToEvents(时间戳:更新)
},
onError:{[weak self]中存在错误
guard let sSelf=self-else{return}
如果let error=error as?LongPollError{
开关错误{
case.olderHistory(let ts):self.subscribeToEvents(时间戳:ts)
默认值:sSelf.getServerConnection()
}
}
})
currentReqursiveConnection?.addDisposableTo(disposeBag)
}
}
私有函数getServerConnection(){
//获取连接的长轮询服务器信息。
currentRequestDisposable=getLongpollServerInfo()
.subscribe(onNext:{[weak self]info in.)
guard let sSelf=self-else{return}
sSelf.currentRequestInfo.value=信息
})
currentRequestDisposable?.addDisposableTo(disposeBag)
}
private func parseUpdates(json:Any)抛出->可观察{
让response=try Mapper().map(JSONObject:json)
return.just(回应)
}
私有函数reciveEvents(更新:LongPollingUpdates)抛出->可见{
如果let errors=updates.failed{
抛出解析错误(错误:错误)
}
如果let events=updates.updates{
解析更新(更新:事件)
}
返回Observable.just(updates.timeStamp!)
}
私有函数解析更新(更新:[[Any]]){
updates.forEach{(数组)位于
让firstElementInUpdate=array.first
如果let update=firstelement更新为?Int{
开关更新{
案例1:休息
案例2:休息
案例3:休息
案例4:MessageReceiver.onNext(NewMessage(数组:数组))
默认值:中断
}
}
}
}
private func parseErrors(错误:[字符串:任意])->LongPollError{
如果let error=errors[“failed”]as?Int{
开关错误{
案例1:
guard let ts=errors[“ts”]as?TimeInterval else{return.unkownError}
返回。旧历史(ts:ts)
案例2:return.needNewkey
案例3:返回。需要案例和
案例4:返回。未知版本
违约:
return.unkownError
}
}
return.unkownError
}
private func getevents fromlongpollserver(serverInfo:LongpollingServerInfo,带ts:TimeInterval)->可观察{
让url=buildLongPollingServerRoute(from:serverInfo,with:ts)
let request=buldlongpollrequest(路由:url)
让requestConvert=try?URLEncoding.default.encode(request!,with:nil)
return transport.makeRequest(请求:requestConvert!)
}
private func getEventsFromLongpollServer(serverInfo:LongpollingServerInfo)->可观察{
让url=buildLongPollingServerRoute(发件人:serverInfo)
let request=buldlongpollrequest(路由:url)
让requestConvert=try?URLEncoding.default.encode(request!,with:nil)
return transport.makeRequest(请求:requestConvert!)
}
private func getLongpollServerInfo()->可观察{
let request=MessageRouter.getLongpollServer(usesl:false,needPts:false)
return transport.makeModel(请求:request)
}
}

因此,假设您有如下函数:

func getData() -> Observable<Data>
你可以用
Observable<Int>.interval(period, scheduler: MainScheduler.instance)
  .map { _ in return }
  .flatMap(getData)
  .subscribe( /* ... handle data ... */)
  .disposed(by: disposeBag)
func handleError(error: Error) -> Observable<Data> {
  return Observable.empty()
}

Observable<Int>.interval(period, scheduler: MainScheduler.instance)
  .map { _ in return }
  .flatMap { return getData.catchError(handleError) }
  .subscribe( /* ... handle data ... */)
  .disposed(by: disposeBag)