parent
23a34838e5
commit
e625e39eb2
@ -0,0 +1,24 @@ |
||||
// |
||||
// URLManager.swift |
||||
// LeStorage |
||||
// |
||||
// Created by Laurent Morvillier on 18/11/2024. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
struct URLManager { |
||||
|
||||
var httpScheme: String |
||||
var domain: String |
||||
private let apiPath: String = "roads" |
||||
|
||||
var api: String { |
||||
return "\(self.httpScheme)\(self.domain)/\(self.apiPath)/" |
||||
} |
||||
|
||||
func websocket(userId: String) -> String { |
||||
return "ws://\(self.domain)/ws/user/\(userId)/" |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,112 @@ |
||||
// |
||||
// WebSocketManager.swift |
||||
// WebSocketTest |
||||
// |
||||
// Created by Laurent Morvillier on 30/08/2024. |
||||
// |
||||
|
||||
import Foundation |
||||
import SwiftUI |
||||
import Combine |
||||
|
||||
class WebSocketManager: ObservableObject { |
||||
|
||||
private var webSocketTask: URLSessionWebSocketTask? |
||||
// @Published var messages: [String] = [] |
||||
private var timer: Timer? |
||||
|
||||
@Published var status: String = "status" |
||||
|
||||
init(urlString: String) { |
||||
setupWebSocket(urlString: urlString) |
||||
} |
||||
|
||||
deinit { |
||||
disconnect() |
||||
} |
||||
|
||||
private func setupWebSocket(urlString: String) { |
||||
// guard let url = URL(string: "ws://127.0.0.1:8000/ws/user/test/") else { |
||||
guard let url = URL(string: urlString) else { |
||||
print("Invalid URL") |
||||
return |
||||
} |
||||
|
||||
let session = URLSession(configuration: .default) |
||||
webSocketTask = session.webSocketTask(with: url) |
||||
webSocketTask?.resume() |
||||
|
||||
receiveMessage() |
||||
|
||||
// Setup a ping timer to keep the connection alive |
||||
timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { _ in |
||||
self.ping() |
||||
} |
||||
} |
||||
|
||||
private func receiveMessage() { |
||||
webSocketTask?.receive { result in |
||||
switch result { |
||||
case .failure(let error): |
||||
self.changeStatus(error.localizedDescription) |
||||
print("Error in receiving message: \(error)") |
||||
|
||||
self.webSocketTask?.resume() |
||||
case .success(let message): |
||||
switch message { |
||||
case .string(let text): |
||||
print("Received text: \(text)") |
||||
Task { |
||||
do { |
||||
try await StoreCenter.main.synchronizeLastUpdates() |
||||
} catch { |
||||
Logger.error(error) |
||||
} |
||||
} |
||||
|
||||
DispatchQueue.main.async { |
||||
// self.messages.append(text) |
||||
} |
||||
case .data(let data): |
||||
print("Received binary message: \(data)") |
||||
@unknown default: |
||||
print("received other = \(message)") |
||||
} |
||||
self.changeStatus("success") |
||||
|
||||
self.receiveMessage() |
||||
} |
||||
} |
||||
} |
||||
|
||||
func changeStatus(_ status: String) { |
||||
DispatchQueue.main.async { |
||||
self.status = status |
||||
} |
||||
} |
||||
|
||||
func send(_ message: String) { |
||||
webSocketTask?.send(.string(message)) { error in |
||||
if let error = error { |
||||
print("Error in sending message: \(error)") |
||||
self.changeStatus("send failed: \(error.localizedDescription)") |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func ping() { |
||||
webSocketTask?.sendPing { error in |
||||
if let error = error { |
||||
print("Error in sending ping: \(error)") |
||||
self.changeStatus("ping failed: \(error.localizedDescription)") |
||||
} |
||||
} |
||||
} |
||||
|
||||
func disconnect() { |
||||
self.changeStatus("disconnected") |
||||
webSocketTask?.cancel(with: .goingAway, reason: nil) |
||||
timer?.invalidate() |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue