ProductPromotion
Logo

Kotlin

made by https://0x3d.site

GitHub - lepicekmichal/SignalRKore: A Kotlin multiplatform coroutine-based SignalR client.
A Kotlin multiplatform coroutine-based SignalR client. - lepicekmichal/SignalRKore
Visit Site

GitHub - lepicekmichal/SignalRKore: A Kotlin multiplatform coroutine-based SignalR client.

GitHub - lepicekmichal/SignalRKore: A Kotlin multiplatform coroutine-based SignalR client.

SignalRKore

Maven Central Kotlin GitHub License Kotlin Weekly

badge-android badge-jvm badge-ios

SignalRKore is a client library connecting to ASP.NET Core server for real-time functionality. Enables server-side code to push content to clients and vice-versa. Instantly.

Why should you use this library

Official client library SignalRKore
Written in Java Kotlin
KMM / KMP :heavy_multiplication_x: Android, JVM, iOS
Network OkHttp only Ktor
Async RxJava Coroutines
Serialization Gson (non-customizable) Kotlinx Serializable (customizable)
Streams :heavy_check_mark: :heavy_check_mark:
Transport fallback :heavy_multiplication_x: :heavy_multiplication_x:
Automatic reconnect :heavy_multiplication_x: :heavy_check_mark:
SSE :heavy_multiplication_x: :heavy_check_mark:
Connection status :heavy_multiplication_x: :heavy_check_mark:
Logging SLF4J Custom interface
MsgPack :heavy_check_mark: :heavy_multiplication_x:
Tested by time & community :heavy_check_mark: :heavy_multiplication_x:

Install

implementation("eu.lepicekmichal.signalrkore:signalrkore:${signalrkoreVersion}")

Usage

Create your hub connection

private val connection: HubConnection = HubConnectionBuilder.create("http://localhost:5000/chat")

Start your connection

connection.start()

Send to server

connection.send("broadcastMessage", "Michal", "Hello")
// or 
connection.invoke("broadcastMessage", "Michal", "Hello")

Receive from server

connection.on("broadcastMessage", paramType1 = String::class, paramType2 = String::class).collect { (user, message) ->
    println("User $user is saying: $message")
}

Receive from server and return result

connection.on("sneakAttack", paramType1 = Boolean::class, resultType = String::class) { surprise ->
    if (surprise) "Wow, you got me"
    else "I saw you waaay from over there"
}

maximizing shorthand style

connection.on("sneakAttack") { surprise: Boolean ->
    if (surprise) "Wow, you got me"
    else "I saw you waaay from over there"
}

Don't forget to stop the connection

connection.stop()

Send and Receive complex data types

// Serializable class
@Serializable
data class Message(
    val id: String,
    val author: String,
    val date: String,
    val text: String,
)

// Sending message
val message = Message(
    id = UUID.next(),
    author = "Michal",
    date = "2022-11-30T21:37:11Z",
    text = "Hello",
)
connection.send("broadcastMessage", message)

// Receiving messages
connection.on("broadcastMessage", Message::class).collect { (message) ->
    println(message.toString())
}

We got streams too

// Receiving
connection.stream(
    method = "Counter",
    itemType = Int::class,
    arg1 = 10, // up to
    arg2 = 500, // delay
).collect {
    println("Countdown: ${10 - it}")
}

// Uploading
// send, invoke or stream methods
connection.send("UploadStream", flow<Int> {
    var data = 0
    while (data < 10) {
        emit(++data)
        delay(500)
    }
})

Receiving stream invocation and responding to it is in

Keep up with connection status

connection.connectionState.collect {
    when (it) {
        HubConnectionState.CONNECTED -> println("Yay, we online")
        HubConnectionState.DISCONNECTED -> println("Shut off!")
        HubConnectionState.CONNECTING -> println("Almost there")
        HubConnectionState.RECONNECTING -> println("Down again")
    }
} 

Connection configuration

HubConnectionBuilder
    .create(url) {
        transportEnum = ...
        httpClient = ...
        protocol = ...
        skipNegotiate = ...
        automaticReconnect = ...
        accessToken = ...
        handshakeResponseTimeout = ...
        headers = ...
        json = ...
        logger = ...
    }

Supported transports

  1. TransportEnum.All (default, automatic choice based on availability)
  2. TransportEnum.WebSockets
  3. TransportEnum.ServerSentEvents
  4. TransportEnum.LongPolling

Add your own ktor http client

For example one with okhttp engine and its builder containing interceptors

httpClient = HttpClient(OkHttp) {
    engine {
        preconfigured = okHttpBuilder.build()
    }
}

But if you do opt-in to pass the http client, make sure it has WebSockets and other plugins installed

HttpClient {
    install(WebSockets)
    install(SSE)
    install(HttpTimeout)
    install(ContentNegotiation) { json() }
}

You may pass your own HubProtocol

With custom parsing and encoding

class MyHubProtocol : HubProtocol {
    fun parseMessages(payload: ByteArray): List<HubMessage> {
        // your implementation
    }

    fun writeMessage(message: HubMessage): ByteArray {
        // your implementation
    }
}

Logs are available

Just decide what to do with the message

logger = Logger { severity, msg, cause ->
    Napier.v("SignalRKore is saying: $ms")
}

Do not forget your own instance of Json

If your kotlinx-serialization Json is customized or it has modules registered in it, then don't forget to pass it.

Reconnect if server wants you to

SignalR Core server can send close message with allowReconnect property set to true.
Automatic reconnect is not default behaviour, but can be simply set up.


import kotlin.random.Random

/** Default, reconnect turned off **/
automaticReconnect = AutomaticReconnect.Inactive

/**
 * Basic reconnect policy
 * waits 0、2、10 and 30 seconds before each attempt to reconnect
 * If all four attempts are unsucessful, reconnect is aborted
 */
automaticReconnect = AutomaticReconnect.Active

/**
 * Extra reconnect policy
 * Each attempt to reconnect is suspended with delay of exponential backoff time
 * In default settings
 *      initially waits 1 second, then 1.5 times more seconds each time
 *      at most 15 tries with highest delay of 60 seconds
 *      all can be adjusted
 */
automaticReconnect = AutomaticReconnect.exponentialBackoff()

/**
 * Custom reconnect policy
 * You can implement anything you find plausible
 */
automaticReconnect = AutomaticReconnect.Custom { previousRetryCount, elapsedTime ->
    // before each attempt wait random time 
    // but at most only the time that we are already trying to reconnect
    delay(Random.nextLong(elapsedTime.inWholeMilliseconds))
}

TODO list

  • Readme
  • Documentation
  • Add example project
  • Fix up ServerSentEvents' http client
  • Add logging
  • Error handling
  • Add tests
  • Implement streams
  • Extend to JVM
  • Extend to iOS
  • Implement transport fallback
  • Implement automatic reconnect
  • Reacting to stream invocation from server

All functionality was possible to implement only thanks to AzureSignalR ChatRoomLocal sample

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory