ChimeHQ / JSONRPC

Swift library for JSON-RPC
BSD 3-Clause "New" or "Revised" License
25 stars 8 forks source link

WebSocket DataChannel #11

Open mattmassicotte opened 8 months ago

mattmassicotte commented 8 months ago

Suggested implementation from @jbromburg:

extension DataChannel {
    static func socket(url: URL) throws -> DataChannel {
        let socketSession: URLSession = .init(configuration: .default)
        let socket: URLSessionWebSocketTask = socketSession.webSocketTask(with: url)

        socket.resume()

        let (stream, continuation) = DataSequence.makeStream()

        Task {
            while socket.state == .running {
                do {
                    let message = try await socket.receive()
                    switch message {
                    case .data(let data):
                        continuation.yield(data)
                    case .string(let string):
                        if let data = string.data(using: .utf8) {
                            continuation.yield(data)
                        }
                    @unknown default:
                        fatalError("Unhandled message type")
                    }
                } catch {
                    continuation.finish()
                    throw error
                }
            }
        }

        let writeHandler: DataChannel.WriteHandler = {
            try await socket.send(.data($0))
        }

        return DataChannel(writeHandler: writeHandler, dataSequence: stream)
    }
}