Play框架的Netty Http服務器實現

Play使用Bootstrap初始化服務器Channel,設置Channel類,EventLoop和Handler等。 (Play沒有使用專爲服務器準備的ServerBoostrap,而是使用更加通用的Bootstrap。這樣就可以自己安排對客戶端Channel的設置)

private def bind(address: InetSocketAddress): (Channel, Source[Channel, _]) = {
  val serverChannelEventLoop = eventLoop.next

  // Watches for channel events, and pushes them through a reactive streams publisher.
  val channelPublisher = new HandlerPublisher(serverChannelEventLoop, classOf[Channel])

  val channelClass = transport match {
    case Native => classOf[EpollServerSocketChannel]
    case Jdk => classOf[NioServerSocketChannel]
  }

  //使用Bootstrap創建服務器Channel
  val bootstrap = new Bootstrap()
    .channel(channelClass)
    .group(serverChannelEventLoop)
    .option(ChannelOption.AUTO_READ, java.lang.Boolean.FALSE) // publisher does ctx.read()
    .handler(channelPublisher)
    .localAddress(address)

  setOptions(bootstrap.option, nettyConfig.getConfig("option"))

  val channel = bootstrap.bind.await().channel()
  //將服務器Channel收集到allChannels中
  allChannels.add(channel)

  //返回服務器Channel, 和Akka Stream Source
  (channel, Source.fromPublisher(channelPublisher))
}

當有新的客戶端連接服務器時,服務器Channel上的Handler HandlerPublisher會讀取到新連接的客戶端Channel,然後將客服端Channel發佈到到Akka Stream。在Akka Stream Sink中進行客戶端Pipeline的設置和Event loop的綁定,並將所有的客戶端Channel收集到NettyServer.allChannels屬性中。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章