DiscordKit: can now get to ready event
This commit is contained in:
@@ -3,25 +3,60 @@ import Foundation
|
||||
import FoundationNetworking
|
||||
#endif
|
||||
|
||||
class GatewayClient {
|
||||
let ws: URLSessionWebSocketTask
|
||||
actor GatewayClient {
|
||||
private let ws: URLSessionWebSocketTask
|
||||
private let token: String
|
||||
private(set) var open = false
|
||||
var sequenceNum: Int? = nil
|
||||
|
||||
init(gatewayURL: URL) {
|
||||
init(gatewayURL: URL, token: String) {
|
||||
ws = URLSession.shared.webSocketTask(with: gatewayURL.appending(component: "?v=10&encoding=json"))
|
||||
self.token = token
|
||||
}
|
||||
|
||||
func openConnection() async throws {
|
||||
func openConnection(intents: Intents) async throws {
|
||||
ws.resume()
|
||||
open = true
|
||||
guard case .hello(let helloMessage) = try await getMessage().d else { throw GatewayError.mismatchedOpcode }
|
||||
dump(helloMessage)
|
||||
Timer.scheduledTimer(withTimeInterval: (helloMessage.heartbeat_interval / 1000.0), repeats: true) {
|
||||
|
||||
|
||||
let heartbeatTask = Task() {
|
||||
try await Task.sleep(for: .milliseconds(Int.random(in: 0...helloMessage.heartbeat_interval)))
|
||||
try await sendHeartbeat()
|
||||
|
||||
while !Task.isCancelled {
|
||||
try await Task.sleep(for: .milliseconds(helloMessage.heartbeat_interval))
|
||||
try await sendHeartbeat()
|
||||
}
|
||||
}
|
||||
|
||||
try await sendIdentify(intents: intents)
|
||||
//dump(try await getMessage())
|
||||
//print("got here")
|
||||
_ = await heartbeatTask.result
|
||||
}
|
||||
|
||||
func sendIdentify(intents: Intents) async throws {
|
||||
let payload = """
|
||||
{
|
||||
"op": 2,
|
||||
"d": {
|
||||
"token": "\(token)",
|
||||
"intents": \(intents.rawValue),
|
||||
"properties": {
|
||||
"os": "linux",
|
||||
"browser": "discordkit",
|
||||
"device": "discordkit"
|
||||
}
|
||||
}
|
||||
}
|
||||
""" // Im lazy
|
||||
try await ws.send(.string(payload))
|
||||
}
|
||||
|
||||
func getMessage() async throws -> GatewayMessage {
|
||||
let wsMessage = try await ws.receive()
|
||||
let wsMessage = try! await ws.receive()
|
||||
print(wsMessage)
|
||||
guard case .string(let str) = wsMessage else { throw GatewayError.invalidMessage }
|
||||
let json = JSONDecoder()
|
||||
let gwMessage = try json.decode(GatewayMessage.self, from: Data(str.utf8))
|
||||
@@ -29,6 +64,26 @@ class GatewayClient {
|
||||
return gwMessage
|
||||
}
|
||||
|
||||
private func sendHeartbeat() async throws {
|
||||
let hbMessage = "{\"op\":1,\"d\":\(sequenceNum == nil ? "null" : String(sequenceNum!))}"
|
||||
print(hbMessage)
|
||||
try await ws.send(.string(hbMessage))
|
||||
}
|
||||
|
||||
var events: AsyncStream<GatewayMessage> {
|
||||
AsyncStream { [self] in
|
||||
guard await open else { return nil }
|
||||
do {
|
||||
let event = try await getMessage()
|
||||
if event.op == 1 { try await sendHeartbeat() }
|
||||
return event
|
||||
} catch {
|
||||
print("Error listening to gateway: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum GatewayError: Error {
|
||||
|
||||
Reference in New Issue
Block a user