backslash-f / observable-websocket-client

Establishes WebSocket connections and publishes received messages and errors ⚡

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

swift-version swift-package-manager platforms build-status license

ObservableWebSocketClient ⚡

A Swift package that establishes WebSocket connections and publishes received messages and errors from an Observable Object.

Usage

Initialization

let websocketURL = URL(string: "wss://websocket-endpoint.com")!
let wsClient = ObservableWebSocketClient(websocketURL: websocketURL)

/*
 A `URLSessionWebSocketTask` is created and resumed just after the
 client initialization. Nothing else is required at this point.
 */

Observation

Connection

wsClient
    .$isConnected
    .sink { isConnected in
        print("isConnected: \(isConnected)")
    }
    .store(in: &cancellables)

Messages

wsClient
    .$codableMessage
    .compactMap{ $0 }
    .sink { codableMessage in
        print("Message: \(codableMessage.messageAsString())")
        // codableMessage.message returns the original `URLSessionWebSocketTask.Message`
    }
    .store(in: &cancellables)

Errors

wsClient
    .$codableError
    .compactMap{ $0 }
    .sink { codableError in
        print("Error: \(codableError.description)")
    }
    .store(in: &cancellables)

Ping/Pong 🏓

Ping Message

Passing in a pingTimerInterval during the client initialization will cause a timer to continuously send the given pingMessage to the WS server, keeping the connection alive:

let websocketURL = URL(string: "wss://endpoint.com")!
let wsClient = ObservableWebSocketClient(
    websocketURL: websocketURL,
    pingTimerInterval: 18, // Every 18 seconds
    pingMessage: "{\"type\": \"ping\"}" // The format is defined by the WS server
)

Ping Message with Generated ID

To generate a unique ID for the ping-type message, use the closure in pingMessageWithGenerateId. The closure takes a String (the generated unique ID), returns a modified version of the message incorporating the ID, and sends it to the WS server. As in the above, these steps are repeated continuously using the interval indicated in the pingTimerInterval, generating unique IDs each time to keep the connection alive:

let websocketURL = URL(string: "wss://endpoint.com")!
let wsClient = ObservableWebSocketClient(
    websocketURL: websocketURL,
    pingTimerInterval: 18, // Every 18 seconds
    pingMessageWithGeneratedId: { generatedId in
        "{\"id\": \"\(generatedId)\", \"type\": \"ping\"}"  // The format is defined by the WS server
    }
)

Sending messages

After the client is initialized and a connection is established, messages can be sent via the ObservableWebSocketClient.sendMessage(_:) API:

wsClient.sendMessage("A String WebSocket message")

Demo

In this demo app, the ObservableWebSocketClient connects to a Kucoin WebSocket server and sends ping messages every pingTimerInterval to keep the connection alive. The server responds with welcome and pong messages:

observable-websocket-client.mp4

Integration

Xcode

Use Xcode's built-in support for SPM.

or...

Package.swift

In your Package.swift, add ObservableWebSocketClient as a dependency:

dependencies: [
  .package(
  	url: "https://github.com/backslash-f/observable-websocket-client",
  	from: "1.0.0"
  )
]

Associate the dependency with your target:

targets: [
  .target(
    name: "YourAppName",
    dependencies: [
      .product(
      	name: "ObservableWebSocketClient",
      	package: "observable-websocket-client"
      )
    ]
  )
]

Run: swift build

About

Establishes WebSocket connections and publishes received messages and errors ⚡

License:MIT License


Languages

Language:Swift 100.0%