Skip to content

Commit

Permalink
Example Bind
Browse files Browse the repository at this point in the history
  • Loading branch information
thalysmbn committed Dec 22, 2021
1 parent fbeb1b5 commit 8c64878
Show file tree
Hide file tree
Showing 20 changed files with 304 additions and 52 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion MMOServer.iml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<compilerSettings />
<compilerArguments>
<stringArguments>
<stringArg name="apiVersion" arg="1.5" />
<stringArg name="apiVersion" arg="1.6" />
<stringArg name="languageVersion" arg="1.6" />
</stringArguments>
<arrayArguments>
Expand All @@ -24,6 +24,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/examples/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
Expand Down Expand Up @@ -68,6 +69,8 @@
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.8.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-core:2.16.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.16.0" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.6.10" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.16.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
Expand Down
12 changes: 12 additions & 0 deletions src/examples/java/MMOServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mmo.core.netty.NettyBootstrap;
import network.NetworkFactory;

import java.time.Duration;

public class MMOServer {

public static void main(String[] args) {
NettyBootstrap bootstrap = new NettyBootstrap(new NetworkFactory(), 10000, Duration.ofSeconds(10));
bootstrap.build();
}
}
12 changes: 12 additions & 0 deletions src/examples/java/network/NetworkFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package network;

import mmo.core.netty.ChannelAdapter;
import mmo.core.session.Session;
import mmo.core.session.SessionFactory;

public class NetworkFactory implements SessionFactory {
@Override
public Session create(ChannelAdapter channel) {
return new NetworkSession(channel);
}
}
33 changes: 33 additions & 0 deletions src/examples/java/network/NetworkSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package network;

import mmo.core.netty.ChannelAdapter;
import mmo.core.network.Channel;
import mmo.core.session.Session;

public class NetworkSession implements Session {
private ChannelAdapter channel;

public NetworkSession(ChannelAdapter channel) {
this.channel = channel;
}

@Override
public void close() {

}

@Override
public void receive(Object msg) {

}

@Override
public void inactive() {

}

@Override
public ChannelAdapter channel() {
return channel;
}
}
2 changes: 1 addition & 1 deletion src/main/java/mmo/core/netty/ChannelAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ChannelAdapter(private val channel: ChannelHandlerContext) : Channel {
override val isAlive: Boolean
get() = channel.channel().isActive

override fun address(): InetSocketAddress? {
override fun address(): InetSocketAddress {
return channel.channel().remoteAddress() as InetSocketAddress
}
}
27 changes: 15 additions & 12 deletions src/main/java/mmo/core/netty/NettyBootstrap.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
package mmo.core.netty

import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.Unpooled
import io.netty.channel.Channel
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInitializer
import io.netty.channel.EventLoopGroup
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.timeout.IdleStateEvent
import io.netty.handler.timeout.IdleStateHandler
import io.netty.handler.codec.DelimiterBasedFrameDecoder
import mmo.core.Server
import mmo.core.netty.codec.MessageDecoder
import mmo.core.network.SessionIdle
import mmo.core.netty.codec.MessageEncoder
import mmo.core.session.Session
import mmo.core.session.SessionFactory
import org.apache.logging.log4j.LogManager
import java.time.Duration
import java.util.concurrent.TimeUnit

class NettyBootstrap<S : Session?>(private val factory: SessionFactory<S>, private val port: Int, private val inactivityDuration: Duration) : Server<S> {
private var channel: Channel? = null
private var eventLoopGroup: EventLoopGroup? = null
private var sessionHandlerAdapter: SessionHandlerAdapter<S>? = null
private val logger = LogManager.getLogger(javaClass)
override fun build() {
logger.info("building netty on network port: {}", port)
val bootstrap = ServerBootstrap()
.group(NioEventLoopGroup(Runtime.getRuntime().availableProcessors()).also { eventLoopGroup = it })
.channel(NioServerSocketChannel::class.java)
.childHandler(object : ChannelInitializer<Channel>() {
override fun initChannel(channel: Channel) {
channel
.pipeline()
//.addLast(DelimiterBasedFrameDecoder(4096, Unpooled.wrappedBuffer(ByteArray(10))))
.addLast(MessageEncoder())
.addLast(MessageDecoder())
.addLast(object : IdleStateHandler(inactivityDuration.toMillis(), 0, 0, TimeUnit.MILLISECONDS) {
@Throws(Exception::class)
override fun channelIdle(ctx: ChannelHandlerContext, evt: IdleStateEvent) {
ctx.fireChannelRead(SessionIdle(inactivityDuration))
}
})
//.addLast(object : IdleStateHandler(inactivityDuration.toMillis(), 0, 0, TimeUnit.MILLISECONDS) {
// @Throws(Exception::class)
// override fun channelIdle(ctx: ChannelHandlerContext, evt: IdleStateEvent) {
// ctx.fireChannelRead(SessionIdle(inactivityDuration))
// }
//})
.addLast(SessionHandlerAdapter(factory).also { sessionHandlerAdapter = it })
}
})
channel = bootstrap.bind(port).channel()
bootstrap.bind(port).also { channel = it.channel() }
}

override fun shutdown() {
Expand Down
21 changes: 14 additions & 7 deletions src/main/java/mmo/core/netty/SessionHandlerAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,44 @@ package mmo.core.netty
import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelId
import io.netty.channel.ChannelInboundHandlerAdapter
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.util.AttributeKey
import mmo.core.session.Session
import mmo.core.session.SessionFactory
import org.apache.logging.log4j.LogManager
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap

@Sharable
class SessionHandlerAdapter<S : Session?>(private val factory: SessionFactory<S>) : ChannelInboundHandlerAdapter() {
class SessionHandlerAdapter<S : Session?>(private val factory: SessionFactory<S>) : SimpleChannelInboundHandler<Any?>() {
private val sessionAttribute = AttributeKey.valueOf<S>("session")
private val sessions: ConcurrentMap<ChannelId, S> = ConcurrentHashMap()
private val logger = LogManager.getLogger(javaClass)
fun sessions(): Collection<S> {
return sessions.values
}

override fun channelActive(ctx: ChannelHandlerContext) {
@Throws(Exception::class)
override fun channelRegistered(ctx: ChannelHandlerContext) {
val session = factory.create(ChannelAdapter(ctx))
logger.info("new connection from address: {}", session!!.channel().address())
ctx
.channel()
.attr(sessionAttribute)
.set(session)
sessions[ctx.channel().id()] = session
}

override fun channelInactive(ctx: ChannelHandlerContext) {
@Throws(Exception::class)
override fun channelUnregistered(ctx: ChannelHandlerContext) {
ctx.channel().attr(sessionAttribute).get()!!.inactive()
}

override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
ctx.channel().attr(sessionAttribute).get()!!.receive(msg)
@Throws(Exception::class)
public override fun channelRead0(ctx: ChannelHandlerContext?, message: Any?) {
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {}
@Throws(Exception::class)
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
}
}
17 changes: 0 additions & 17 deletions src/main/java/mmo/core/netty/codec/MessageDecoder.java

This file was deleted.

12 changes: 12 additions & 0 deletions src/main/java/mmo/core/netty/codec/MessageDecoder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mmo.core.netty.codec

import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.ByteToMessageDecoder

class MessageDecoder : ByteToMessageDecoder() {
@Throws(Exception::class)
override fun decode(ctx: ChannelHandlerContext, `in`: ByteBuf, out: List<Any>) {
if (`in`.readableBytes() < 6) return
}
}
11 changes: 11 additions & 0 deletions src/main/java/mmo/core/netty/codec/MessageEncoder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mmo.core.netty.codec

import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.MessageToByteEncoder

class MessageEncoder : MessageToByteEncoder<Any?>() {
@Throws(Exception::class)
override fun encode(channelHandlerContext: ChannelHandlerContext, o: Any?, byteBuf: ByteBuf) {
}
}
5 changes: 3 additions & 2 deletions src/main/java/mmo/core/network/Channel.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package mmo.core.network

import io.netty.channel.ChannelId
import java.net.InetSocketAddress

interface Channel {
/**
* Get the channel id
*/
fun id(): Any?
fun id(): ChannelId?

/**
* Write message to the channel
Expand All @@ -28,5 +29,5 @@ interface Channel {
/**
* Get the client address
*/
fun address(): InetSocketAddress?
fun address(): InetSocketAddress
}
7 changes: 1 addition & 6 deletions src/main/java/mmo/core/session/Session.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ package mmo.core.session
import mmo.core.netty.ChannelAdapter

interface Session {
/**
* Check if the session is alive
*/
val isAlive: Boolean

/**
* Close the session
*/
Expand All @@ -28,5 +23,5 @@ interface Session {
/**
* Return IO channel
*/
fun channel(): ChannelAdapter?
fun channel(): ChannelAdapter
}
2 changes: 1 addition & 1 deletion src/main/java/mmo/core/session/SessionFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ interface SessionFactory<S : Session?> {
/**
* Create the session from the channel
*/
fun create(channel: ChannelAdapter?): S
fun create(channel: ChannelAdapter): S
}
Loading

0 comments on commit 8c64878

Please sign in to comment.