Skip to content

Instantly share code, notes, and snippets.

@Jire
Created October 27, 2016 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jire/0cae53e6312536a626f5b6e7c6f83515 to your computer and use it in GitHub Desktop.
Save Jire/0cae53e6312536a626f5b6e7c6f83515 to your computer and use it in GitHub Desktop.
package org.jire.knetty
import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.*
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.DatagramChannel
import io.netty.channel.socket.DatagramPacket
import io.netty.channel.socket.nio.NioDatagramChannel
import io.netty.handler.codec.MessageToMessageDecoder
import java.util.*
class UDPServer(val group: EventLoopGroup, val channel: Class<out Channel>) {
val decoder = Decoder()
fun bind(port: Int) = Bootstrap().group(group).handler(Handler(decoder)).channel(channel).bind(port)
inner class IncomingPackets {
internal operator fun Int.invoke(body: ByteBuf.() -> Unit) {
decoder.handlers.put(this, body)
}
}
internal inline fun incoming(body: IncomingPackets.() -> Unit) {
IncomingPackets().body()
}
}
internal class Handler(val decoder: Decoder) : ChannelInitializer<DatagramChannel>() {
override fun initChannel(ch: DatagramChannel) {
ch.pipeline().addFirst(decoder)
}
}
inline fun udp(group: EventLoopGroup = NioEventLoopGroup(),
channel: Class<out Channel> = NioDatagramChannel::class.java,
init: UDPServer.() -> Unit): UDPServer {
val server = UDPServer(group, channel)
server.init()
return server
}
class Decoder : MessageToMessageDecoder<DatagramPacket>() {
override fun decode(ctx: ChannelHandlerContext, msg: DatagramPacket, out: MutableList<Any>) = with(session!!) {
read = msg.content()
if (read.readableBytes() > 0) {
val id = read.readUnsignedByte().toInt()
handlers[id]!!(read)
}
}
val handlers = HashMap<Int, ByteBuf.() -> Unit>()
var onActive: (ChannelHandlerContext.() -> Unit)? = null
var onUnregister: (ChannelHandlerContext.() -> Unit)? = null
var onException: (ChannelHandlerContext.(Throwable) -> Unit)? = null
private var session: Session? = null
/* override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
println("read eh")
}*/
override fun channelActive(ctx: ChannelHandlerContext) {
session = Session(ctx.channel())
onActive?.invoke(ctx)
}
override fun channelUnregistered(ctx: ChannelHandlerContext) {
session?.disconnect()
session = null
onUnregister?.invoke(ctx)
}
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
onException?.invoke(ctx, cause)
}
}
class Session(val channel: Channel, var write: ByteBuf? = null) {
lateinit var read: ByteBuf
fun disconnect() {
println("disconnected session")
}
}
fun incomingHandler(block: ByteBuf.() -> Unit) = block
val handleLogin = incomingHandler {
println("hi bud")
}
fun main(args: Array<String>) {
udp {
incoming {
0(handleLogin)
1 {
println("popcorn bud")
}
}
}.bind(43594).await()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment