5 Commits
Author SHA1 Message Date
RTAkland 896883a3e0 Support event hooking 2025-10-31 06:51:13 +08:00
RTAkland 2328bf7755 Add unregister function 2025-10-29 11:12:17 +08:00
RTAkland 6ab5e551e2 Update README.md 2025-10-27 10:46:51 +08:00
RTAkland 33239c6591 Update README 2025-09-30 18:02:03 +08:00
RTAkland 42651a7f81 Published to maven central 2025-09-30 17:51:11 +08:00
5 changed files with 143 additions and 31 deletions

No files matched your search

+26 -14
View File
@@ -2,7 +2,9 @@
A Kotlin multiplatform library for mdns announcer(mdns server), only broadcast is supported,
Also, nmdns can be compiled to shared/static lib for other language calling, see [c++ example](#cpp)
Also, nmdns can be compiled to shared/static lib for other languages calling, see [c++ example](#cpp)
mDNS is usually used for Apple's AirPlay protocol family, there's an example in README.md [How to use](#How-to-use)
Supported platforms:
1. windows64(mingwx64)
@@ -12,9 +14,14 @@ Supported platforms:
5. macosX64
6. jvm(11 or later)
Supported srv type
Supported record type
1. A
2. PTR
3. SRV
4. TXT
Supported features
1. Event hooking(Kotlin only)
> AAAA is not supported
@@ -22,16 +29,7 @@ AirPlay2(_airplay._tcp.local.) is tested
# How to use
Add maven repository
```kotlin
repositories {
mavenCentral()
maven("https://repo.maven.rtast.cn/releases")
}
```
Add dependency
> Make sure you added the mavenCentral repository in your project
```kotlin
kotlin {
@@ -58,10 +56,24 @@ val service = registerService(
bindAddress = "192.168.10.104",
mdnsPort = 5356,
txtRecords = listOf("key1=value1", "key2=value2")
)
) {
// This block is optional
// Event hooking in this block
onBroadcast {
println("broadcasted")
}
onRegister {
println("reg")
}
onUnregistered {
println("unreg")
}
}
while (true) {
service.broadcast()
delay(2000L) // or use cn.rtast.nmdns.sleep1(2) sleep 2 seconds
delay(2000L) // or use cn.rtast.nmdns.sleep1(2) sleep 2 seconds, this function is not a suspended function
}
```
+45 -3
View File
@@ -1,12 +1,16 @@
import com.vanniktech.maven.publish.SonatypeHost
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
kotlin("multiplatform") version "2.2.0"
id("maven-publish")
id("com.vanniktech.maven.publish") version "0.31.0-rc2"
id("signing")
}
val libVersion: String by project
group = "cn.rtast.nmdns"
version = "0.1.0"
version = libVersion
repositories {
mavenCentral()
@@ -48,7 +52,8 @@ kotlin {
}
}
publishing {
mavenPublishing {
publishing {
repositories {
mavenLocal()
maven("https://repo.maven.rtast.cn/releases") {
@@ -58,6 +63,43 @@ publishing {
password = System.getenv("PUBLISH_TOKEN")
}
}
mavenCentral()
}
}
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
if (System.getenv("PUBLISH_TOKEN") == null) signAllPublications()
coordinates("cn.rtast.nmdns", project.name, libVersion)
pom {
name = project.name
description = "mDNS in kotlin multiplatform"
url = "https://github.com/RTAkland/native-mdns"
developers {
developer {
id = "rtakland"
name = "RTAkland"
email = "rtakland@outlook.com"
}
}
licenses {
license {
name = "The Apache License, Version 2.0"
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
}
}
scm {
url = "https://github.com/RTAkland/native-mdns"
connection = "scm:git:git://github.com/RTAkland/native-mdns.git"
developerConnection = "scm:git:ssh://git@github.com/RTAkland/native-mdns.git"
}
}
}
if (System.getenv("PUBLISH_TOKEN") == null) {
signing {
useGpgCmd()
sign(publishing.publications)
}
}
+1
View File
@@ -1,2 +1,3 @@
kotlin.code.style=official
kotlin.native.enableKlibsCrossCompilation=true
libVersion=0.1.2
@@ -12,6 +12,18 @@ package cn.rtast.nmdns
import kotlin.experimental.ExperimentalNativeApi
import kotlin.native.CName
public fun NMDNSAnnouncer.onRegister(callback: () -> Unit) {
onRegisterCallback = callback
}
public fun NMDNSAnnouncer.onBroadcast(callback: () -> Unit) {
onBroadcastCallback = callback
}
public fun NMDNSAnnouncer.onUnregistered(callback: () -> Unit) {
onUnregisterCallback = callback
}
public data class NMDNSAnnouncer(
/**
* service type
@@ -51,6 +63,11 @@ public data class NMDNSAnnouncer(
*/
internal val packet: ByteArray,
) {
internal var onRegisterCallback: (() -> Unit)? = null
internal var onBroadcastCallback: (() -> Unit)? = null
internal var onUnregisterCallback: (() -> Unit)? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
@@ -87,11 +104,21 @@ public data class NMDNSAnnouncer(
* broadcast packet
*/
public fun broadcast() {
this.onBroadcastCallback?.invoke()
this.server.send(packet)
}
/**
* unregister service
*/
public fun unregister() {
this.onUnregisterCallback?.invoke()
this.server.destroy()
}
}
/**
* broadcast packet
* export for c
*/
@CExport
@@ -100,6 +127,16 @@ public fun broadcast1(server: NMDNSAnnouncer) {
server.server.send(server.packet)
}
/**
* unregister service
* export for c
*/
@CExport
@CName("unregister")
public fun unregister1(server: NMDNSAnnouncer) {
server.unregister()
}
/**
* register service
* airplay2 txt records
@@ -121,10 +158,12 @@ public fun registerService(
mdnsPort: Int = 9872,
bindAddress: String,
txtRecords: List<String>,
callback: NMDNSAnnouncer.() -> Unit = {},
): NMDNSAnnouncer {
val server = createSocket()
val socket = createSocket()
.bind(bindAddress, port)
return NMDNSAnnouncer(
val server = NMDNSAnnouncer(
serviceType,
serviceName,
hostname,
@@ -132,9 +171,12 @@ public fun registerService(
port,
mdnsPort,
txtRecords,
server,
buildPacket(serviceType, "$serviceName.$serviceType", hostname, ipAddress, port, txtRecords)
socket,
buildPacket(serviceType, "$serviceName.$serviceType", hostname, ipAddress, port, txtRecords),
)
server.callback()
server.onRegisterCallback?.invoke()
return server
}
internal fun buildPacket(
+16 -1
View File
@@ -7,6 +7,9 @@
package test
import cn.rtast.nmdns.onBroadcast
import cn.rtast.nmdns.onRegister
import cn.rtast.nmdns.onUnregistered
import cn.rtast.nmdns.randomMacAddress
import cn.rtast.nmdns.registerService
import cn.rtast.nmdns.sleep1
@@ -30,7 +33,19 @@ class TestLinux {
"srcvers=220.68",
"pk=f3769a660475d27b4f6040381d784645e13e21c53e6d2da6a8c3d757086fc336"
)
)
) {
onBroadcast {
println(111)
}
onRegister {
println("reg")
}
onUnregistered {
println("unreg")
}
}
while (true) {
service.broadcast()
sleep1(2)