107 lines
3.5 KiB
Swift
107 lines
3.5 KiB
Swift
//
|
|
// NetworkServiceApiWebSockets.swift
|
|
// Wallet
|
|
//
|
|
// Created by Saveliy Stavitsky on 1/15/21.
|
|
// Copyright © 2021 AM. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import Starscream
|
|
|
|
extension Notification.Name {
|
|
static let socketDidConnect = Self("Network.Service.WebSockets.socketDidConnect")
|
|
static let socketDidUpdateValue = Self("Network.Service.WebSockets.socketDidUpdateValue")
|
|
static let socketDidDisconnect = Self("Network.Service.WebSockets.socketDidDisconnect")
|
|
}
|
|
|
|
extension Network.Service {
|
|
class WebSockets: Common.Service.Provider {
|
|
private var timer: Timer?
|
|
private var reconectTimer: Timer?
|
|
private var collection = [String:Subscription]()
|
|
init() {
|
|
timer = delayed(45, repeats: true) { self.update() }
|
|
reconectTimer = delayed(1, repeats: true) { self.reconect() }
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Network.Service.WebSockets {
|
|
func open(subscription: String, id: String) {
|
|
collection[id] = Subscription(id: id, subscription: subscription)
|
|
}
|
|
func remove(id: String) {
|
|
collection[id] = nil
|
|
}
|
|
func remove(idPrefix prefix: String) {
|
|
let toRemoveIds = collection.filter({ $0.key.hasPrefix(prefix) }).map({ $0.key })
|
|
for id in toRemoveIds {
|
|
collection[id] = nil
|
|
}
|
|
}
|
|
func remove(idSuffix suffix: String) {
|
|
let toRemoveIds = collection.filter({ $0.key.hasSuffix(suffix) }).map({ $0.key })
|
|
for id in toRemoveIds {
|
|
collection[id] = nil
|
|
}
|
|
}
|
|
func removeAll() {
|
|
collection = [:]
|
|
}
|
|
}
|
|
|
|
extension Network.Service.WebSockets {
|
|
private func update() {
|
|
for subscription in collection {
|
|
if !subscription.value.socket.isConnected {
|
|
subscription.value.socket.connect()
|
|
} else {
|
|
subscription.value.socket.write(ping: Data())
|
|
}
|
|
}
|
|
}
|
|
private func reconect() {
|
|
for subscription in collection {
|
|
if !subscription.value.socket.isConnected {
|
|
subscription.value.socket.connect()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Network.Service.WebSockets {
|
|
fileprivate class Subscription {
|
|
let socket: WebSocket
|
|
let id: String
|
|
let subscription: String?
|
|
deinit { socket.disconnect() }
|
|
init(id: String, subscription: String?) {
|
|
self.id = id
|
|
self.subscription = subscription
|
|
var request = URLRequest(url: URL(string: Network.servers.current.webSocket)!)
|
|
request.timeoutInterval = 5
|
|
socket = WebSocket(request: request)
|
|
socket.delegate = self
|
|
socket.connect()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Network.Service.WebSockets.Subscription: WebSocketDelegate {
|
|
func websocketDidConnect(socket: WebSocketClient) {
|
|
if let subscription = subscription { socket.write(string: subscription) }
|
|
Notification.post(name: .socketDidConnect, userInfo: ["id": id])
|
|
}
|
|
func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
|
|
socket.connect()
|
|
Notification.post(name: .socketDidDisconnect, userInfo: ["id": id])
|
|
}
|
|
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
|
|
Notification.post(name: .socketDidUpdateValue, userInfo: ["id": id, "data": text])
|
|
}
|
|
func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
|
|
Notification.post(name: .socketDidUpdateValue, userInfo: ["id": id, "data": String(data: data, encoding: .utf8) ?? ""])
|
|
}
|
|
}
|