//
|
// SocketManager.swift
|
// TicketDriverProject
|
//
|
// Created by alvin_y on 2018/8/6.
|
// Copyright © 2018年 yang-wang. All rights reserved.
|
//
|
|
import UIKit
|
import RHSocketKit
|
import RxSwift
|
import RxCocoa
|
import HandyJSON
|
import MBProgressHUD
|
|
/// 正式分享
|
let share_url = "https://zhentonggongsi.com:8443"
|
|
/// 测试网分享
|
//let share_url = "39.108.148.228:8080"
|
/// 测试外网
|
//let Host = "39.108.148.228"
|
|
/// Sockt管理类
|
class YYSocketManager: NSObject {
|
|
//仿OC写法
|
static let instance: YYSocketManager = YYSocketManager()
|
|
/// MBProgressHUD
|
var hud : MBProgressHUD?
|
|
/// DisposeBag
|
private var timeDisposeBag = DisposeBag()
|
|
class func shared() -> YYSocketManager {
|
return instance
|
}
|
|
/// 订单信息
|
let orderInfosubject = PublishSubject<SocketModel>()
|
|
/// 司机取消订单【推送】用户
|
let cancel = PublishSubject<SocketModel>()
|
|
/// 司机位置
|
let position = PublishSubject<SocketModel>()
|
|
/// viewModel
|
let viewModel = TravelServiceViewModel()
|
|
/// 弹出框
|
weak var popupView: YYPopupView?
|
|
override init() {
|
super.init()
|
initNotificationCenter()
|
bindRx()
|
}
|
|
|
func initNotificationCenter() {
|
NotificationCenter.default.addObserver(self, selector: #selector(detectSocketServiceState(notif:)), name: NSNotification.Name(rawValue: kNotificationSocketServiceState), object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(detectSocketPacketResponse(notif:)), name: NSNotification.Name(rawValue: kNotificationSocketPacketResponse), object: nil)
|
}
|
|
/// 开始
|
func startSocket() {
|
if !RHSocketService.sharedInstance().isRunning{
|
//方便多次观察,先停止之前的连接
|
YYSocketManager.shared().stopSocket()
|
let encoder = RHSocketVariableLengthEncoder()
|
let decoder = RHSocketVariableLengthDecoder()
|
encoder.countOfLengthByte = 4
|
decoder.countOfLengthByte = 4
|
RHSocketService.sharedInstance().encoder = encoder
|
RHSocketService.sharedInstance().decoder = decoder
|
let param = RHSocketConnectParam()
|
param.host = SocketHost
|
param.port = Int32(SocketPort)
|
//心跳间隔
|
param.heartbeatInterval = 5
|
//设置短线后是否自动重连
|
param.autoReconnect = true
|
RHSocketService.sharedInstance().start(with: param)
|
}
|
}
|
|
/// Socket是否在运行
|
/// - Returns: BOOL
|
func isRunning() -> Bool {
|
return RHSocketService.sharedInstance().isRunning
|
}
|
|
/// 停止
|
private func stopSocket() {
|
RHSocketService.sharedInstance().stop()
|
}
|
|
//MARK: - socket状态
|
@objc func detectSocketServiceState(notif:NSNotification) {
|
if let state = notif.object {
|
if state as? Bool == true{
|
//链接成功
|
Observable<Int>.interval(RxTimeInterval.seconds(5), scheduler: MainScheduler.instance)
|
.subscribe(onNext: { [unowned self](_) in
|
self.heartBeat()
|
}).disposed(by: timeDisposeBag)
|
loggerswift.success(s: "socket链接成功")
|
}else{
|
//链接失败
|
self.timeDisposeBag = DisposeBag()
|
loggerswift.error(s: "socket链接失败")
|
}
|
}else{
|
//链接失败
|
self.timeDisposeBag = DisposeBag()
|
loggerswift.error(s: "socket链接失败")
|
}
|
}
|
|
//MARK: - 解析接收长连接信息
|
func decodeResponse(notification:NSNotification) -> NSDictionary {
|
if notification.object != nil {
|
return (notification.object as! NSDictionary)
|
}
|
if let userInfo:Dictionary = notification.userInfo {
|
let rsp:RHSocketPacketResponse = userInfo["RHSocketPacket"] as! RHSocketPacketResponse
|
// let strEncode = CFStringConvertEncodingToNSStringEncoding(UInt32(CFStringEncodings.GB_18030_2000.rawValue))
|
|
if let data:Data = rsp.object as? Data{
|
let result = String.init(data: data, encoding: .utf8)
|
let newData = result?.data(using: String.Encoding.utf8)
|
guard let data = newData else{
|
return [:]
|
}
|
let dic = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
|
if let dict:NSDictionary = dic as? NSDictionary{
|
|
return dict
|
}else{
|
return [:]
|
}
|
|
}else{
|
return [:]
|
}
|
|
}else{
|
return [:]
|
}
|
}
|
|
//MARK: - socket接收信息
|
@objc func detectSocketPacketResponse(notif:NSNotification) {
|
let dic = decodeResponse(notification: notif)
|
|
let info = SocketModel.deserialize(from: dic)
|
|
guard let model = info else {return}
|
loggerswift.log(s: dic)
|
if model.code == 200 && model.msg == "SUCCESS" {
|
loggerswift.log(s: "长链接方式:\(model.method)")
|
if model.method != "OK"{
|
// loggerswift.log(s: "长链接已连接")
|
}
|
if model.method == "OK"{
|
}
|
// 用户取消订单【推送】司机
|
else if (model.method == "ORDER_CANCLE"){
|
cancel.onNext(model)
|
}
|
// 服务端下发订单状态格式
|
else if (model.method == "ORDER_STATUS"){
|
//订单推送
|
orderInfosubject.onNext(model)
|
if (model.data?.orderType == 4 || model.data?.orderType == 5) && model.data?.state == 6{
|
ObtainCouponView.giveAwayMerchantCoupon(orderId: model.data!.orderId, orderType: OrderType(rawValue: model.data!.orderType)!, vc: (LD_currentViewController() as! YYViewController))
|
}
|
}
|
// 司机位置
|
else if (model.method == "DRIVER_POSITION"){
|
//订单推送
|
position.onNext(model)
|
}else if (model.method == "FERRY"){
|
// 跨城
|
orderInfosubject.onNext(model)
|
}else if (model.method == "REASSIGN"){
|
// 改派
|
orderInfosubject.onNext(model)
|
}
|
|
// 附近暂无司机接单
|
else if (model.method == "END_PUSH"){
|
guard let orderId = model.data?.orderId,let orderType = model.data?.orderType else {return}
|
viewModel.orderId.accept(orderId)
|
viewModel.orderType.accept(OrderType(rawValue: orderType) ?? .taxi)
|
if popupView == nil{
|
popupView = YYPopupView.instance(type: .double)
|
popupView?.label_title.text = "提示"
|
popupView?.label_content.text = "附近暂无司机接单,您是否继续等待?"
|
popupView?.button_cancel.setTitle("取消订单", for: .normal)
|
popupView?.button_submit.setTitle("继续等待", for: .normal)
|
popupView?.button_close.isHidden = false
|
popupView?.pressSubmitBlock = {[unowned self] in
|
self.viewModel.pushOrderTaxi()
|
self.popupView = nil
|
}
|
popupView?.pressCancelBlock = {[unowned self] in
|
self.viewModel.addCancle()
|
self.popupView = nil
|
}
|
app.window?.addSubview(popupView!)
|
popupView?.show()
|
}
|
}
|
// 多端登录下线
|
else if (model.method == "OFFLINE"){
|
NotificationCenter.default.post(Notification.init(name: Notification.Name(rawValue: TokenInvalid)))
|
if popupView == nil{
|
app.loginInfo.clear()
|
app.userInfo.clear()
|
popupView = YYPopupView.instance(type: .single)
|
popupView?.label_title.text = "提示"
|
popupView?.label_content.text = "您的账号已在其他地方登录,请重新登录"
|
popupView?.button_cancel.setTitle("取消", for: .normal)
|
popupView?.button_submit.setTitle("确定", for: .normal)
|
popupView?.button_close.isHidden = true
|
app.window?.addSubview(popupView!)
|
popupView?.show()
|
}
|
}
|
|
}
|
|
}
|
|
|
//MARK: - Rx
|
func bindRx() {
|
/// 添加取消记录
|
viewModel.addCancleSubject
|
.subscribeOn(MainScheduler.instance)
|
.subscribe(onNext: { (status) in
|
switch status{
|
case .loading:
|
self.show()
|
break
|
case .success(_ ):
|
self.hide()
|
alert(text: "取消成功")
|
UIViewController.base()?.navigationController?.popToRootViewController(animated: true)
|
break
|
case .error(let error):
|
self.hide()
|
alert(text: error.localizedDescription)
|
break
|
}
|
}).disposed(by: rx.disposeBag)
|
|
/// 继续等待订单
|
viewModel.pushOrderTaxiTaxiSubject
|
.subscribeOn(MainScheduler.instance)
|
.subscribe(onNext: { (status) in
|
switch status{
|
case .loading:
|
self.show()
|
break
|
case .success(_ ):
|
self.hide()
|
break
|
case .error(let error):
|
self.hide()
|
alert(text: error.localizedDescription)
|
break
|
}
|
}).disposed(by: rx.disposeBag)
|
}
|
|
func heartBeat() {
|
if app.loginInfo.id == 0 || app.loginInfo.token == "" {
|
return
|
}
|
let dict = ["code": 200,
|
"msg": "SUCCESS",
|
"method": "PING",
|
"data": ["type": 1,"userId": app.loginInfo.id,"token": app.loginInfo.token]] as [String : Any]
|
let jsonString = dict.dictionaryToJson()
|
guard let string = jsonString else {return}
|
let request = RHSocketPacketRequest()
|
request.object = string.data(using: String.Encoding.utf8)
|
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNotificationSocketPacketRequest), object: request)
|
}
|
|
/*
|
func uploadLocation() {
|
let dict:JSON = ["con":["id":app.loginInfo.id,"orderId":app.loginInfo.orderId,"lon":app.loginInfo.lon,"lat":app.loginInfo.lat],"method":"LOCATION","code":"\(0)","msg":"SUCCESS"]
|
let jsonString = dict.rawString([.castNilToNSNull: true])
|
guard let string = jsonString else {return}
|
let request = RHSocketPacketRequest()
|
request.object = string.data(using: String.Encoding.utf8)
|
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNotificationSocketPacketRequest), object: request)
|
}
|
*/
|
|
//MARK: - MBProgressHUD
|
/// 不带文字
|
func show() {
|
hud = build()
|
}
|
|
func hide() {
|
hud?.hide(animated: true)
|
}
|
|
private func build() -> MBProgressHUD {
|
let hud = MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true)
|
hud.mode = .indeterminate
|
hud.bezelView.style = .solidColor
|
hud.bezelView.color = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.7)
|
hud.customView?.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
|
return hud
|
}
|
}
|
// MARK: - UIViewControllerTransitioningDelegate
|
extension YYSocketManager: UIViewControllerTransitioningDelegate{
|
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
return DismissAnimation()
|
}
|
|
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
return PresentAnimation()
|
}
|
}
|