Skip to content

Instantly share code, notes, and snippets.

@volgar1x
Last active December 25, 2015 23:49
Show Gist options
  • Save volgar1x/7059706 to your computer and use it in GitHub Desktop.
Save volgar1x/7059706 to your computer and use it in GitHub Desktop.
package org.photon.login
import com.twitter.util.Future
trait NetClient {
type NetService
def service: NetService
def closeFuture: Future[this.type]
def write(o: Any): Future[this.type]
def flush(): Future[this.type]
def !(o: Any) = write(o) flatMap (_.flush())
def close(): Future[this.type]
}
trait NetServiceComponent {
type NetClient <: org.photon.login.NetClient
val netService: NetService
trait NetService {
def boot(): Future[this.type]
def kill(): Future[this.type]
def connected: Seq[NetClient]
}
}
package org.photon.login
import com.twitter.util.{Promise, Future}
import scala.collection.mutable
import org.photon.login.NetClientImpl.NetService
import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter, Channel, ChannelInitializer}
import io.netty.channel.socket.SocketChannel
import java.net.InetSocketAddress
import io.netty.util.concurrent.GenericFutureListener
trait NetServiceComponentImpl extends NetServiceComponent { self: ConfigurationComponent =>
implicit def fn2GenericFutureListener(fn: => Unit) = new GenericFutureListener[Nothing] {
def operationComplete(future: Nothing) = fn
}
type NetClient = NetClientImpl
val netService = new NetServiceImpl
private[this] val _config = config.atKey("photon.network.login")
class NetClientImpl(channel: Channel) extends org.photon.login.NetClient {
type NetService = NetServiceImpl
private val _closePromise = Promise[this.type]
def service = netService
def closeFuture: Future[this.type] = _closePromise
def write(o: Any): Future[this.type] = {
val promise = Promise[this.type]
channel.write(o) addListener { promise setValue this }
promise
}
def flush(): Future[this.type] = {
channel.flush()
Future(this)
}
def close(): Future[this.type] = {
channel.close() addListener { _closePromise setValue this }
closeFuture
}
}
class NetServiceImpl extends NetService {
private val _server =
new ServerBootstrap()
.group(new NioEventLoopGroup, new NioEventLoopGroup)
.childHandler(new ChannelInitializer[SocketChannel] {
def initChannel(ch: SocketChannel) {
ch.pipeline
.addLast("handler", new NetServiceHandlerImpl)
}
})
.channel(classOf[NioServerSocketChannel])
.register().sync().channel()
private val _connected = mutable.ArrayBuffer.empty[NetClient]
def connected = _connected.toSeq
def boot(): Future[this.type] = {
val promise = Promise[this.type]
_server.bind(new InetSocketAddress(_config.getInt("port")))
.addListener { promise setValue this }
promise
}
def kill(): Future[this.type] = {
val promise = Promise[this.type]
_server.closeFuture()
.addListener { promise setValue this }
promise
}
}
private[this] class NetServiceHandlerImpl extends ChannelInboundHandlerAdapter {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment