Dev

Building Real-Time Crypto Prices in CoinHaus — The WebSocket Battle

2021-10-26·2min read

Why Polling Doesn't Work Here

Crypto prices move dozens of times per second. Showing them in real time with repeated HTTP requests (polling) means flooding the server with calls and draining the battery — not acceptable.

The answer is WebSocket: open a persistent connection and let the server push data to the client whenever prices change. One connection, live updates.

The problem: every exchange implements WebSocket differently.

Three Exchanges, Three Protocols

Upbit sends data as binary messages and expects a JSON array of subscribed coin codes to be sent immediately after the connection opens.

Bithumb uses plain text JSON messages with a simpler subscription format.

Binance embeds the stream name directly in the WebSocket URL — no separate subscription message needed.

I had to read each exchange's API documentation carefully, implement the connection and subscription logic separately for each, and parse their unique response formats.

Abstracting to a Common Interface

Managing three different WebSocket implementations separately would make the codebase fragile. Every time an exchange changed their API, I'd be digging into three separate codepaths.

I defined a shared protocol:

protocol ExchangeWebSocket {
    var exchange: Exchange { get }
    func connect(coins: [String])
    func disconnect()
    var onPriceUpdate: ((PriceData) -> Void)? { get set }
}

Each exchange implementation conforms to this and handles its own connection mechanics internally. The UI layer only sees PriceData — it doesn't care which exchange it came from or how the connection was established.

Handling Disconnections

WebSocket connections drop. Server maintenance, network switches, the app going to the background — any of these can close the connection.

I built automatic reconnection with exponential backoff: retry after 1 second, then 2, then 4, up to a maximum of 30 seconds between attempts. When the app comes back to the foreground, reconnect immediately by observing scenePhase changes.

The Result

The first time I saw all three exchanges updating live on the same screen — prices ticking in near real time, side by side — it was one of the most satisfying moments in building this app.

WebSocket implementation was the hardest technical challenge in CoinHaus. It was worth figuring out.

Next: building the community features on top of this price layer.