5.7 KiB
lyng.io.net — TCP and UDP sockets for Lyng scripts
This module provides minimal raw transport networking for Lyng scripts. It is implemented in lyngio and backed by Ktor sockets on the JVM and Linux Native, and by Node networking APIs on JS/Node runtimes.
Note:
lyngiois a separate library module. It must be explicitly added as a dependency to your host application and initialized in your Lyng scopes.Important native platform limit: current native TCP/UDP support is backed by a selector with a per-process file descriptor ceiling. On Linux/macOS native targets this makes high-connection-count servers and same-process load tests unsuitable once the process approaches that limit.
Recommendation: for serious HTTP/TCP servers, prefer the JVM target today. On native targets, keep concurrency bounded, batch local load tests in waves, and use multiple worker processes behind a reverse proxy if you need more throughput before the backend is reworked.
Need this fixed? Please open or upvote an issue at https://github.com/sergeych/lyng/issues so native high-concurrency networking can be prioritized.
Install the module into a Lyng session
Kotlin (host) bootstrap example:
import net.sergeych.lyng.EvalSession
import net.sergeych.lyng.Scope
import net.sergeych.lyng.io.net.createNetModule
import net.sergeych.lyngio.net.security.PermitAllNetAccessPolicy
suspend fun bootstrapNet() {
val session = EvalSession()
val scope: Scope = session.getScope()
createNetModule(PermitAllNetAccessPolicy, scope)
session.eval("import lyng.io.net")
}
Using from Lyng scripts
Capability checks and address resolution:
import lyng.io.net
val a: SocketAddress = Net.resolve("127.0.0.1", 4040)[0]
[Net.isSupported(), a.toString(), a.resolved, a.ipVersion == IpVersion.IPV4]
>>> [true,127.0.0.1:4040,true,true]
TCP client connect, write, read, and close:
import lyng.buffer
import lyng.io.net
val socket = Net.tcpConnect("127.0.0.1", NET_TEST_TCP_PORT)
socket.writeUtf8("ping")
socket.flush()
val reply = (socket.read(16) as Buffer).decodeUtf8()
socket.close()
reply
>>> "reply:ping"
Lyng TCP server socket operations with tcpListen() and accept():
import lyng.buffer
import lyng.io.net
val server = Net.tcpListen(0, "127.0.0.1")
val port = server.localAddress().port
val accepted = launch {
val client = server.accept()
val line = (client.read(4) as Buffer).decodeUtf8()
client.writeUtf8("echo:" + line)
client.flush()
client.close()
server.close()
line
}
val socket = Net.tcpConnect("127.0.0.1", port)
socket.writeUtf8("ping")
socket.flush()
val reply = (socket.read(16) as Buffer).decodeUtf8()
socket.close()
[accepted.await(), reply]
>>> [ping,echo:ping]
UDP bind, send, receive, and inspect sender address:
import lyng.buffer
import lyng.io.net
val server = Net.udpBind(0, "127.0.0.1")
val client = Net.udpBind(0, "127.0.0.1")
client.send(Buffer("ping"), "127.0.0.1", server.localAddress().port)
val d = server.receive()
client.close()
server.close()
[d.data.decodeUtf8(), d.address.port > 0]
>>> [ping,true]
API reference
Net (static methods)
isSupported(): Bool— Whether any raw networking support is available.isTcpAvailable(): Bool— Whether outbound TCP sockets are available.isTcpServerAvailable(): Bool— Whether listening TCP server sockets are available.isUdpAvailable(): Bool— Whether UDP datagram sockets are available.resolve(host: String, port: Int): List<SocketAddress>— Resolve a host and port into concrete addresses.tcpConnect(host: String, port: Int, timeoutMillis: Int? = null, noDelay: Bool = true): TcpSocket— Open an outbound TCP socket.tcpListen(port: Int, host: String? = null, backlog: Int = 128, reuseAddress: Bool = true): TcpServer— Start a listening TCP server socket.udpBind(port: Int = 0, host: String? = null, reuseAddress: Bool = true): UdpSocket— Bind a UDP socket.
SocketAddress
host: Stringport: IntipVersion: IpVersionresolved: BooltoString(): String
TcpSocket
isOpen(): BoollocalAddress(): SocketAddressremoteAddress(): SocketAddressread(maxBytes: Int = 65536): Buffer?readLine(): String?write(data: Buffer): voidwriteUtf8(text: String): voidflush(): voidclose(): void
TcpServer
isOpen(): BoollocalAddress(): SocketAddressaccept(): TcpSocketclose(): void
UdpSocket
isOpen(): BoollocalAddress(): SocketAddressreceive(maxBytes: Int = 65536): Datagram?send(data: Buffer, host: String, port: Int): voidclose(): void
Datagram
data: Bufferaddress: SocketAddress
Security policy
The module uses NetAccessPolicy to authorize network operations before they are executed.
NetAccessPolicy— interface for custom policiesPermitAllNetAccessPolicy— allows all network operationsNetAccessOp.Resolve(host, port)NetAccessOp.TcpConnect(host, port)NetAccessOp.TcpListen(host, port, backlog)NetAccessOp.UdpBind(host, port)
Platform support
- JVM: supported
- Android: supported via the Ktor CIO and Ktor sockets backends
- JS/Node: supported for
resolve, TCP client/server, and UDP - JS/browser: unsupported; capability checks report unavailable
- Linux Native: supported via Ktor sockets
- Apple Native: enabled via the shared native Ktor sockets backend; compile-verified, runtime not yet host-verified
- Other native targets: currently report unsupported; use capability checks before relying on raw sockets