Skip to content

Commit e480d6c

Browse files
authored
Fix #1 (#4)
* add a simple demo * publish to mavel central * fix ut
1 parent 8da5f03 commit e480d6c

File tree

30 files changed

+720
-69
lines changed

30 files changed

+720
-69
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 HackWebRTC
3+
Copyright (c) 2025 HackWebRTC
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 117 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,123 @@
11
# kmp-socketio
22

3-
KMP implementation of SocketIO client.
3+
KMP (pure Kotlin) implementation of SocketIO client.
44

5-
![Main branch status](https://github.com/HackWebRTC/kmp-socketio/actions/workflows/test_and_run_demo.yaml/badge.svg?branch=main)
5+
![Maven Central Version](https://img.shields.io/maven-central/v/com.piasy/kmp-socketio) ![Main branch status](https://github.com/HackWebRTC/kmp-socketio/actions/workflows/test_and_run_demo.yaml/badge.svg?branch=main)
6+
7+
## Supported platforms
8+
9+
| Platform | 🛠Builds🛠 + 🔬Tests🔬 |
10+
| :----------------: | :------------------: |
11+
| `JVM` 17 | 🚀 |
12+
| `Browser` (Chrome) | 🚀 |
13+
| `Android` | 🚀 |
14+
| `iOS` | 🚀 |
15+
| `MacOS` | 🚀 |
16+
| `Windows X64` | 🚀 |
17+
| `Linux X64` | 🔮 |
18+
19+
About Linux support: Ktor's curl engine doesn't support websockets now,
20+
although CIO engine supports websockets, but it doesn't support TLS.
21+
22+
Ref:
23+
24+
- [Native Sockets TLS Client/Server support for linux](https://github.com/ktorio/ktor/pull/2939)
25+
- [Possible websockets support for curl engine](https://github.com/whyoleg/ktor/tree/libcurl-ws)
26+
27+
## Dependency
28+
29+
You only need to add gradle dependency:
30+
31+
```kotlin
32+
// add common source set dependency
33+
kotlin {
34+
sourceSets {
35+
val commonMain by getting {
36+
dependencies {
37+
implementation("com.piasy:kmp-socketio:$version")
38+
}
39+
}
40+
}
41+
}
42+
```
43+
44+
## Usage
45+
46+
```kotlin
47+
IO.socket("http://localhost:3000", IO.Options()) { socket ->
48+
socket.on(Socket.EVENT_CONNECT) { args ->
49+
println("on connect ${args.joinToString()}")
50+
51+
socket.emit("echo", 1, "2", GMTDate())
52+
}.on("echoBack") { args ->
53+
println("on echoBack ${args.joinToString()}")
54+
}
55+
56+
socket.open()
57+
}
58+
```
59+
60+
## Example
61+
62+
### Android
63+
64+
Open the project (the repo root dir) in Android studio, and run the example.androidApp target.
65+
66+
### iOS
67+
68+
```bash
69+
cd example/iosApp
70+
pod install
71+
# open iosApp.xcworkspace in Xcode, and run it.
72+
```
73+
74+
### JS
75+
76+
Use Chrome CORS Unblock extension to workaround with CORS error.
77+
78+
```bash
79+
./gradlew :example:shared:jsBrowserRun
80+
```
81+
82+
### Windows
83+
84+
```bash
85+
.\gradlew runKmp_socketioDebugExecutableMingwX64
86+
```
87+
88+
### macOS
89+
90+
```bash
91+
./gradlew runKmp_socketioDebugExecutableMacosX64
92+
```
93+
94+
## Publish
95+
96+
Maven central portal credentials and signing configs are set in `~/.gradle/gradle.properties`.
97+
98+
```bash
99+
# on Windows: need manual release on website
100+
.\gradlew clean publishMingwX64PublicationToMavenCentralRepository --no-configuration-cache
101+
# on macOS: need manual release on website
102+
./gradlew clean \
103+
publishKotlinMultiplatformPublicationToMavenCentralRepository \
104+
publishJvmPublicationToMavenCentralRepository \
105+
publishIosArm64PublicationToMavenCentralRepository \
106+
publishIosSimulatorArm64PublicationToMavenCentralRepository \
107+
publishIosX64PublicationToMavenCentralRepository \
108+
publishMacosArm64PublicationToMavenCentralRepository \
109+
publishMacosX64PublicationToMavenCentralRepository \
110+
publishJsPublicationToMavenCentralRepository \
111+
--no-configuration-cache
112+
```
113+
114+
Login to https://central.sonatype.com/publishing/deployments, and release them manually.
6115

7116
## Credit
8117

9-
+ [joffrey-bion/socketio-kotlin](https://github.com/joffrey-bion/socketio-kotlin)
10-
+ [dyte-io/socketio-kotlin](https://github.com/dyte-io/socketio-kotlin)
11-
+ [socketio/socket.io-client-java](https://github.com/socketio/socket.io-client-java)
12-
+ [socketio/engine.io-client-java](https://github.com/socketio/engine.io-client-java)
13-
+ [socketio/socket.io](https://github.com/socketio/socket.io)
14-
+ [ktorio/ktor](https://github.com/ktorio/ktor)
118+
- [joffrey-bion/socketio-kotlin](https://github.com/joffrey-bion/socketio-kotlin)
119+
- [dyte-io/socketio-kotlin](https://github.com/dyte-io/socketio-kotlin)
120+
- [socketio/socket.io-client-java](https://github.com/socketio/socket.io-client-java)
121+
- [socketio/engine.io-client-java](https://github.com/socketio/engine.io-client-java)
122+
- [socketio/socket.io](https://github.com/socketio/socket.io)
123+
- [ktorio/ktor](https://github.com/ktorio/ktor)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
plugins {
2+
alias(libs.plugins.android.application)
3+
alias(libs.plugins.kotlin.android)
4+
alias(libs.plugins.compose.compiler)
5+
}
6+
7+
android {
8+
namespace = "${Consts.androidNS.replace('_', '.')}.android"
9+
compileSdk = libs.versions.compileSdk.get().toInt()
10+
defaultConfig {
11+
applicationId = "${Consts.androidNS.replace('_', '.')}.android"
12+
minSdk = libs.versions.minSdk.get().toInt()
13+
targetSdk = libs.versions.targetSdk.get().toInt()
14+
versionCode = 1
15+
versionName = Consts.releaseVersion
16+
}
17+
buildFeatures {
18+
compose = true
19+
}
20+
21+
compileOptions {
22+
sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get().toInt())
23+
targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get().toInt())
24+
}
25+
26+
kotlin {
27+
jvmToolchain(libs.versions.jvm.get().toInt())
28+
}
29+
packaging {
30+
resources {
31+
excludes += "/META-INF/{AL2.0,LGPL2.1}"
32+
}
33+
}
34+
buildTypes {
35+
getByName("release") {
36+
isMinifyEnabled = false
37+
}
38+
}
39+
}
40+
41+
dependencies {
42+
implementation(project(":example:shared"))
43+
implementation(libs.androidx.compose.ui)
44+
implementation(libs.androidx.compose.ui.tooling)
45+
implementation(libs.androidx.compose.ui.tooling.preview)
46+
implementation(libs.androidx.compose.foundation)
47+
implementation(libs.androidx.compose.material)
48+
implementation(libs.androidx.activity.compose)
49+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
6+
<application
7+
android:allowBackup="false"
8+
android:supportsRtl="true"
9+
android:theme="@style/AppTheme">
10+
<activity
11+
android:name=".MainActivity"
12+
android:exported="true">
13+
<intent-filter>
14+
<action android:name="android.intent.action.MAIN" />
15+
<category android:name="android.intent.category.LAUNCHER" />
16+
</intent-filter>
17+
</activity>
18+
</application>
19+
</manifest>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.piasy.kmp.socketio.android
2+
3+
import android.os.Bundle
4+
import androidx.activity.ComponentActivity
5+
import androidx.activity.compose.setContent
6+
import androidx.compose.foundation.isSystemInDarkTheme
7+
import androidx.compose.foundation.layout.Box
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.shape.RoundedCornerShape
10+
import androidx.compose.material.MaterialTheme
11+
import androidx.compose.material.Shapes
12+
import androidx.compose.material.Surface
13+
import androidx.compose.material.Text
14+
import androidx.compose.material.Typography
15+
import androidx.compose.material.darkColors
16+
import androidx.compose.material.lightColors
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.ui.Alignment
19+
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.graphics.Color
21+
import androidx.compose.ui.text.TextStyle
22+
import androidx.compose.ui.text.font.FontFamily
23+
import androidx.compose.ui.text.font.FontWeight
24+
import androidx.compose.ui.tooling.preview.Preview
25+
import androidx.compose.ui.unit.dp
26+
import androidx.compose.ui.unit.sp
27+
import com.piasy.kmp.socketio.example.Greeting
28+
29+
@Composable
30+
fun MyApplicationTheme(
31+
darkTheme: Boolean = isSystemInDarkTheme(),
32+
content: @Composable () -> Unit
33+
) {
34+
val colors = if (darkTheme) {
35+
darkColors(
36+
primary = Color(0xFFBB86FC),
37+
primaryVariant = Color(0xFF3700B3),
38+
secondary = Color(0xFF03DAC5)
39+
)
40+
} else {
41+
lightColors(
42+
primary = Color(0xFF6200EE),
43+
primaryVariant = Color(0xFF3700B3),
44+
secondary = Color(0xFF03DAC5)
45+
)
46+
}
47+
val typography = Typography(
48+
body1 = TextStyle(
49+
fontFamily = FontFamily.Default,
50+
fontWeight = FontWeight.Normal,
51+
fontSize = 16.sp
52+
)
53+
)
54+
val shapes = Shapes(
55+
small = RoundedCornerShape(4.dp),
56+
medium = RoundedCornerShape(4.dp),
57+
large = RoundedCornerShape(0.dp)
58+
)
59+
60+
MaterialTheme(
61+
colors = colors,
62+
typography = typography,
63+
shapes = shapes,
64+
content = content
65+
)
66+
}
67+
68+
class MainActivity : ComponentActivity() {
69+
override fun onCreate(savedInstanceState: Bundle?) {
70+
super.onCreate(savedInstanceState)
71+
72+
setContent {
73+
MyApplicationTheme {
74+
Surface(
75+
modifier = Modifier.fillMaxSize(),
76+
color = MaterialTheme.colors.background
77+
) {
78+
Box(
79+
modifier = Modifier.fillMaxSize(),
80+
contentAlignment = Alignment.Center,
81+
) {
82+
Greeting("hello world")
83+
}
84+
}
85+
}
86+
}
87+
88+
Greeting().greet()
89+
}
90+
}
91+
92+
@Composable
93+
fun Greeting(text: String) {
94+
Text(text = text)
95+
}
96+
97+
@Preview
98+
@Composable
99+
fun DefaultPreview() {
100+
MyApplicationTheme {
101+
Greeting("Hello, Android!")
102+
}
103+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<style name="AppTheme" parent="android:Theme.Material.NoActionBar"/>
3+
</resources>

example/iosApp/Podfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
source 'https://cdn.cocoapods.org'
2+
3+
target 'iosApp' do
4+
use_frameworks!
5+
platform :ios, '14.0'
6+
pod 'shared', :path => '../shared'
7+
end

example/iosApp/iosApp.xcworkspace/contents.xcworkspacedata

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"colors" : [
3+
{
4+
"idiom" : "universal"
5+
}
6+
],
7+
"info" : {
8+
"author" : "xcode",
9+
"version" : 1
10+
}
11+
}

0 commit comments

Comments
 (0)