io.netty.channel.nio.NioEventLoopGroup Scala Examples

The following examples show how to use io.netty.channel.nio.NioEventLoopGroup. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: InvalidBootstrapClient.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.oio.OioSocketChannel
import java.net.InetSocketAddress


  def bootstrap(): Unit = {
    val group = new NioEventLoopGroup
    //创建一个新的 Bootstrap 类的实例,以创建新的客户端Channel
    val bootstrap = new Bootstrap
    //指定一个适用于 NIO 的 EventLoopGroup 实现
    bootstrap.group(group)
      //指定一个适用于 OIO 的 Channel 实现类
      .channel(classOf[OioSocketChannel])
      //设置一个用于处理 Channel的 I/O 事件和数据的 ChannelInboundHandler
      .handler {
        new SimpleChannelInboundHandler[ByteBuf]() {
          @throws[Exception]
          override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = {
            println("Received data")
          }
        }
      }
    //尝试连接到远程节点
    val future = bootstrap.connect(new InetSocketAddress("www.manning.com", 80))
    future.syncUninterruptibly
  }
} 
Example 2
Source File: FrontendService.scala    From spark-sql-server   with Apache License 2.0 5 votes vote down vote up
package org.apache.spark.sql.server.service

import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.logging.{LoggingHandler, LogLevel}

import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.server.SQLServerConf._

private[service] abstract class FrontendService extends CompositeService {

  var port: Int = _
  var workerThreads: Int = _
  var bossGroup: NioEventLoopGroup = _
  var workerGroup: NioEventLoopGroup = _

  def messageHandler: ChannelInitializer[SocketChannel]

  override def doInit(conf: SQLConf): Unit = {
    port = conf.sqlServerPort
    workerThreads = conf.sqlServerWorkerThreads
    bossGroup = new NioEventLoopGroup(1)
    workerGroup = new NioEventLoopGroup(workerThreads)
  }

  override def doStart(): Unit = {
    try {
      val b = new ServerBootstrap()
        // .option(ChannelOption.SO_KEEPALIVE, true)
        .group(bossGroup, workerGroup)
        .channel(classOf[NioServerSocketChannel])
        .handler(new LoggingHandler(LogLevel.INFO))
        .childHandler(messageHandler)

      // Binds and starts to accept incoming connections
      val f = b.bind(port).sync()

      // Blocked until the server socket is closed
      logInfo(s"Start running the SQL server (port=$port, workerThreads=$workerThreads)")
      f.channel().closeFuture().sync();
    } finally {
      bossGroup.shutdownGracefully()
      workerGroup.shutdownGracefully()
    }
  }
} 
Example 3
Source File: SocketSpec.scala    From asyncdb   with Apache License 2.0 5 votes vote down vote up
package io.asyncdb
package netty
package mysql

import cats.effect._
import io.netty.bootstrap._
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio._
import java.net.InetSocketAddress
import scala.concurrent.{Future, ExecutionContext}
import scala.language.implicitConversions

abstract class SocketSpec extends Spec {

  implicit val contextShift                = IO.contextShift(ExecutionContext.global)

  implicit def effectAsFuture[A](f: IO[A]) = f.unsafeToFuture

  protected val config = {
    val host: String = "127.0.0.1"
    val port: Int    = 3306
    val address      = new InetSocketAddress(host, port)
    val b = (new Bootstrap)
      .remoteAddress(address)
      .group(new NioEventLoopGroup())
      .channel(classOf[NioSocketChannel])
    MySQLSocketConfig(
      bootstrap = b,
      charset = CharsetMap.Utf8_general_ci,
      database = Some("asyncdb"),
      username = "asyncdb",
      password = Some("asyncdb"),
      authMethod = None
    )
  }

  protected def withSocket[A](cfg: MySQLSocketConfig)(f: MySQLSocket[IO] => IO[A]): IO[A] = {
    Resource.make(MySQLSocket[IO](cfg).flatMap(_.connect))(_.disconnect).use(f)
  }

  protected def withSocket[A](f: MySQLSocket[IO] => IO[A]): IO[A] = withSocket[A](config)(f)

} 
Example 4
Source File: NettyUtils.scala    From aloha   with Apache License 2.0 5 votes vote down vote up
package me.jrwang.aloha.transport.util

import io.netty.buffer.PooledByteBufAllocator
import io.netty.channel.{Channel, EventLoopGroup, ServerChannel}
import io.netty.channel.epoll.{EpollEventLoopGroup, EpollServerSocketChannel, EpollSocketChannel}
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.{NioServerSocketChannel, NioSocketChannel}
import io.netty.util.concurrent.DefaultThreadFactory
import io.netty.util.internal.PlatformDependent
import me.jrwang.aloha.common.Logging


object NettyUtils extends Logging {
  
  private def getPrivateStaticField(name: String) = try {
    val f = PooledByteBufAllocator.DEFAULT.getClass.getDeclaredField(name)
    f.setAccessible(true)
    f.getInt(null)
  } catch {
    case e: Exception =>
      throw new RuntimeException(e)
  }
} 
Example 5
Source File: NetworkClient.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.network.client

import java.io.IOException
import java.net.InetSocketAddress

import com.wavesplatform.Version
import com.wavesplatform.network.{Handshake, TrafficLogger}
import com.wavesplatform.settings._
import com.wavesplatform.utils.ScorexLogging
import io.netty.bootstrap.Bootstrap
import io.netty.channel._
import io.netty.channel.group.ChannelGroup
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel

import scala.concurrent.{Future, Promise}

class NetworkClient(trafficLoggerSettings: TrafficLogger.Settings, chainId: Char, nodeName: String, nonce: Long, allChannels: ChannelGroup) extends ScorexLogging {

  private val workerGroup = new NioEventLoopGroup()
  private val handshake   = Handshake(Constants.ApplicationName + chainId, Version.VersionTuple, nodeName, nonce, None)

  def connect(remoteAddress: InetSocketAddress): Future[Channel] = {
    val p = Promise[Channel]

    val bootstrap = new Bootstrap()
      .group(workerGroup)
      .channel(classOf[NioSocketChannel])
      .handler(new LegacyChannelInitializer(trafficLoggerSettings, handshake, p))

    log.debug(s"Connecting to $remoteAddress")
    val channelFuture = bootstrap.connect(remoteAddress)
    channelFuture.addListener((_: io.netty.util.concurrent.Future[Void]) => {
      log.debug(s"Connected to $remoteAddress")
      channelFuture.channel().write(p)
    })

    val channel = channelFuture.channel()
    allChannels.add(channel)
    channel.closeFuture().addListener { (chf: ChannelFuture) =>
      if (!p.isCompleted) {
        val cause = Option(chf.cause()).getOrElse(new IllegalStateException("The connection is closed before handshake"))
        p.failure(new IOException(cause))
      }
      log.debug(s"Connection to $remoteAddress closed")
      allChannels.remove(chf.channel())
    }

    p.future
  }

  def shutdown(): Unit =
    try {
      allChannels.close().await()
      log.debug("Closed all channels")
    } finally {
      workerGroup.shutdownGracefully()
    }
} 
Example 6
Source File: PacketProxy.scala    From Neutrino   with Apache License 2.0 5 votes vote down vote up
package com.ebay.neutrino

import java.net.{InetAddress, InetSocketAddress, SocketAddress}
import com.ebay.neutrino.util.Utilities

import scala.concurrent.Future
import scala.util.{Failure, Success}

import com.typesafe.scalalogging.slf4j.StrictLogging
import io.netty.bootstrap.{Bootstrap, ServerBootstrap}
import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel._
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.{NioServerSocketChannel, NioSocketChannel}
import io.netty.util.AttributeKey



  override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef) {
    println("Writing packet from downstream to upstream...")
    upstream.writeAndFlush(msg)
    //ctx.fireChannelRead(msg)
  }

  override def channelInactive(ctx: ChannelHandlerContext): Unit = {
    println("Downstream closing..")
    upstream.close()
    ctx.fireChannelInactive()
  }
} 
Example 7
Source File: GrpcGatewayServerBuilder.scala    From grpcgateway   with MIT License 5 votes vote down vote up
package grpcgateway.server

import grpcgateway.handlers.{GrpcGatewayHandler, MethodNotFoundHandler, SwaggerHandler}
import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.codec.http.{HttpObjectAggregator, HttpServerCodec}


case class GrpcGatewayServerBuilder(
  port: Int = 80,
  services: Seq[GrpcGatewayHandler] = Nil
) {

  def forPort(port: Int): GrpcGatewayServerBuilder = {
    copy(port = port)
  }

  def addService(service: GrpcGatewayHandler): GrpcGatewayServerBuilder = {
    copy(services = services :+ service)
  }

  def build(): GrpcGatewayServer = {
    val masterGroup = new NioEventLoopGroup()
    val slaveGroup = new NioEventLoopGroup()
    val bootstrap = new ServerBootstrap()
    bootstrap
      .group(masterGroup, slaveGroup)
      .channel(classOf[NioServerSocketChannel])
      .childHandler(new ChannelInitializer[SocketChannel] {
        override def initChannel(ch: SocketChannel): Unit = {
          ch.pipeline().addLast("codec", new HttpServerCodec())
          ch.pipeline().addLast("aggregator", new HttpObjectAggregator(512 * 1024))
          ch.pipeline().addLast("swagger", new SwaggerHandler(services))
          services.foreach { handler =>
            ch.pipeline().addLast(handler.name, handler)
          }
          ch.pipeline().addLast(new MethodNotFoundHandler())
        }
      })

    new GrpcGatewayServer(port, bootstrap, masterGroup, slaveGroup, services.toList)
  }

}

object GrpcGatewayServerBuilder {
  def forPort(port: Int): GrpcGatewayServerBuilder =
    new GrpcGatewayServerBuilder().forPort(port)
  def addService(service: GrpcGatewayHandler): GrpcGatewayServerBuilder =
    new GrpcGatewayServerBuilder().addService(service)
} 
Example 8
Source File: BootstrapWithInitializer.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

import io.netty.bootstrap.ServerBootstrap
import io.netty.channel._
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.codec.http.HttpClientCodec
import io.netty.handler.codec.http.HttpObjectAggregator
import java.net.InetSocketAddress


  @throws[InterruptedException]
  def bootstrap(): Unit = {
    //创建 ServerBootstrap 以创建和绑定新的 Channel
    val bootstrap = new ServerBootstrap

    //设置 EventLoopGroup,其将提供用以处理 Channel 事件的 EventLoop
    bootstrap.group(new NioEventLoopGroup, new NioEventLoopGroup)
      .channel(classOf[NioServerSocketChannel]) //指定 Channel 的实现
      //注册一个 ChannelInitializerImpl 的实例来设置 ChannelPipeline
      .childHandler(new ChannelInitializerImpl)

    //绑定到地址
    val future = bootstrap.bind(new InetSocketAddress(8080))
    future.sync
  }

  //用以设置 ChannelPipeline 的自定义 ChannelInitializerImpl 实现
  final private[chapter8] class ChannelInitializerImpl extends ChannelInitializer[Channel] {
    //将所需的 ChannelHandler 添加到 ChannelPipeline
    @throws[Exception]
    override protected def initChannel(ch: Channel): Unit = {
      val pipeline = ch.pipeline
      pipeline.addLast(new HttpClientCodec)
      pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE))
    }
  }
} 
Example 9
Source File: BootstrapClientWithOptionsAndAttrs.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelOption
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.util.AttributeKey
import java.net.InetSocketAddress
import java.lang.{ Boolean ⇒ JBoolean }


  def bootstrap(): Unit = { //创建一个 AttributeKey 以标识该属性
    val id: AttributeKey[Integer] = AttributeKey.newInstance("ID")
    //创建一个 Bootstrap 类的实例以创建客户端 Channel 并连接它们
    val bootstrap = new Bootstrap
    //设置 EventLoopGroup,其提供了用以处理 Channel 事件的 EventLoop
    bootstrap.group(new NioEventLoopGroup)
      .channel(classOf[NioSocketChannel])
      .handler(new SimpleChannelInboundHandler[ByteBuf]() {
        @throws[Exception]
        override def channelRegistered(ctx: ChannelHandlerContext): Unit = { //使用 AttributeKey 检索属性以及它的值
          val idValue = ctx.channel.attr(id).get
          // do something with the idValue
        }

        @throws[Exception]
        override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = {
          System.out.println("Received data")
        }
      })

    //设置 ChannelOption,其将在 connect()或者bind()方法被调用时被设置到已经创建的 Channel 上
    bootstrap
      .option[JBoolean](ChannelOption.SO_KEEPALIVE, true)
      .option[Integer](ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)

    //存储该 id 属性
    bootstrap.attr[Integer](id, 123456)

    //使用配置好的 Bootstrap 实例连接到远程主机
    val future = bootstrap.connect(new InetSocketAddress("www.manning.com", 80))
    future.syncUninterruptibly
  }
} 
Example 10
Source File: BootstrapServer.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelFuture
import io.netty.channel.ChannelFutureListener
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import java.net.InetSocketAddress


  def bootstrap(): Unit = {
    val group = new NioEventLoopGroup
    //创建 Server Bootstrap
    val bootstrap = new ServerBootstrap
    //设置 EventLoopGroup,其提供了用于处理 Channel 事件的EventLoop
    bootstrap.group(group)
      //指定要使用的 Channel 实现
      .channel(classOf[NioServerSocketChannel])
      //设置用于处理已被接受的子 Channel 的I/O及数据的 ChannelInboundHandler
      .childHandler {
        new SimpleChannelInboundHandler[ByteBuf]() {
          @throws[Exception]
          override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = {
            System.out.println("Received data")
          }
        }
      }

    //通过配置好的 ServerBootstrap 的实例绑定该 Channel
    val future = bootstrap.bind(new InetSocketAddress(8080))
    future.addListener(new ChannelFutureListener() {
      @throws[Exception]
      override def operationComplete(channelFuture: ChannelFuture): Unit = {
        if (channelFuture.isSuccess) System.out.println("Server bound")
        else {
          System.err.println("Bind attempt failed")
          channelFuture.cause.printStackTrace()
        }
      }
    })
  }
} 
Example 11
Source File: BootstrapSharingEventLoopGroup.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

import io.netty.bootstrap.Bootstrap
import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelFuture
import io.netty.channel.ChannelFutureListener
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.channel.socket.nio.NioSocketChannel
import java.net.InetSocketAddress


  def bootstrap(): Unit = { //创建 ServerBootstrap 以创建 ServerSocketChannel,并绑定它
    val bootstrap = new ServerBootstrap
    //设置 EventLoopGroup,其将提供用以处理 Channel 事件的 EventLoop
    bootstrap.group(new NioEventLoopGroup, new NioEventLoopGroup)
      //指定要使用的 Channel 实现
      .channel(classOf[NioServerSocketChannel])
      //设置用于处理已被接受的子 Channel 的 I/O 和数据的 ChannelInboundHandler
      .childHandler {
        new SimpleChannelInboundHandler[ByteBuf]() {
          private[chapter8] var connectFuture: ChannelFuture = _

          @throws[Exception]
          override def channelActive(ctx: ChannelHandlerContext): Unit = {
            //创建一个 Bootstrap 类的实例以连接到远程主机
            val bootstrap = new Bootstrap
            //指定 Channel 的实现
            bootstrap.channel(classOf[NioSocketChannel])
              .handler(new SimpleChannelInboundHandler[ByteBuf]() {
                @throws[Exception]
                override protected def channelRead0(
                  ctx: ChannelHandlerContext,
                  in:  ByteBuf): Unit = {
                  println("Received data")
                }
              })
            //使用与分配给已被接受的子Channel相同的EventLoop
            bootstrap.group(ctx.channel.eventLoop)
            //连接到远程节点
            connectFuture = bootstrap.connect(new InetSocketAddress("www.manning.com", 80))
          }

          @throws[Exception]
          override protected def channelRead0(
            channelHandlerContext: ChannelHandlerContext,
            byteBuf:               ByteBuf): Unit = {
            if (connectFuture.isDone) {
              //当连接完成时,执行一些数据操作(如代理)
              // do something with the data
            }
          }
        }
      }

    //通过配置好的 ServerBootstrap 绑定该 ServerSocketChannel
    val future = bootstrap.bind(new InetSocketAddress(8080))
    future.addListener(new ChannelFutureListener() {
      @throws[Exception]
      override def operationComplete(channelFuture: ChannelFuture): Unit = {
        if (channelFuture.isSuccess) System.out.println("Server bound")
        else {
          System.err.println("Bind attempt failed")
          channelFuture.cause.printStackTrace()
        }
      }
    })
  }
} 
Example 12
Source File: GracefulShutdown.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

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.nio.NioSocketChannel
import io.netty.util.concurrent.Future
import java.net.InetSocketAddress


  def bootstrap(): Unit = {
    //创建处理 I/O 的EventLoopGroup
    val group = new NioEventLoopGroup

    //创建一个 Bootstrap 类的实例并配置它
    val bootstrap = new Bootstrap
    bootstrap.group(group)
      .channel(classOf[NioSocketChannel])
      .handler(
        new SimpleChannelInboundHandler[ByteBuf]() {
          @throws[Exception]
          override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = {
            System.out.println("Received data")
          }
        }
      )
    bootstrap.connect(new InetSocketAddress("www.manning.com", 80)).syncUninterruptibly()

    //shutdownGracefully()方法将释放所有的资源,并且关闭所有的当前正在使用中的 Channel
    val future = group.shutdownGracefully()
    // block until the group has shutdown
    future.syncUninterruptibly()
  }
} 
Example 13
Source File: EventLoopGroupOwner.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.platform.apiserver

import java.util.UUID
import java.util.concurrent.TimeUnit.MILLISECONDS

import com.daml.resources.{Resource, ResourceOwner}
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.{NioServerSocketChannel, NioSocketChannel}
import io.netty.channel.{Channel, EventLoopGroup, ServerChannel}
import io.netty.util.concurrent.DefaultThreadFactory

import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.util.Try

final class EventLoopGroupOwner(threadPoolName: String, parallelism: Int)
    extends ResourceOwner[EventLoopGroup] {

  override def acquire()(implicit executionContext: ExecutionContext): Resource[EventLoopGroup] =
    Resource(
      Future(new NioEventLoopGroup(
        parallelism,
        new DefaultThreadFactory(s"$threadPoolName-grpc-event-loop-${UUID.randomUUID()}", true))))(
      group => {
        val promise = Promise[Unit]()
        val future = group.shutdownGracefully(0, 0, MILLISECONDS)
        future.addListener((f: io.netty.util.concurrent.Future[_]) =>
          promise.complete(Try(f.get).map(_ => ())))
        promise.future
      }
    )
}

object EventLoopGroupOwner {

  val clientChannelType: Class[_ <: Channel] = classOf[NioSocketChannel]

  val serverChannelType: Class[_ <: ServerChannel] = classOf[NioServerSocketChannel]

} 
Example 14
Source File: BootstrapClient.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter8

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.nio.NioSocketChannel
import java.net.InetSocketAddress


  def bootstrap(): Unit = {
    //设置 EventLoopGroup,提供用于处理 Channel 事件的 EventLoop
    val group: EventLoopGroup = new NioEventLoopGroup
    //创建一个Bootstrap类的实例以创建和连接新的客户端Channel
    val bootstrap = new Bootstrap
    bootstrap.group(group)
      //指定要使用的Channel 实现
      .channel(classOf[NioSocketChannel])
      //设置用于 Channel 事件和数据的ChannelInboundHandler
      .handler {
        new SimpleChannelInboundHandler[ByteBuf]() {
          @throws[Exception]
          override protected def channelRead0(
            channelHandlerContext: ChannelHandlerContext,
            byteBuf:               ByteBuf): Unit = {
            println("Received data")
          }
        }
      }
    //连接到远程主机
    val future = bootstrap.connect(new InetSocketAddress("www.manning.com", 80))
    future.addListener(new ChannelFutureListener() {
      @throws[Exception]
      override def operationComplete(channelFuture: ChannelFuture): Unit = {
        if (channelFuture.isSuccess)
          println("Connection established")
        else {
          System.err.println("Connection attempt failed")
          channelFuture.cause.printStackTrace()
        }
      }
    })
  }
} 
Example 15
Source File: EchoClient.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter2.echoclient

import io.netty.bootstrap.Bootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.EventLoopGroup
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioSocketChannel
import java.net.InetSocketAddress


object EchoClient {
  @throws[Exception]
  def main(args: Array[String]): Unit = {
    if (args.length != 2) {
      System.err.println("Usage: " + classOf[EchoClient].getSimpleName + " <host> <port>")
    } else {
      val host = args(0)
      val port = args(1).toInt
      new EchoClient(host, port).start()
    }
  }
}

class EchoClient(val host: String, val port: Int) {
  @throws[Exception]
  def start(): Unit = {
    val group: EventLoopGroup = new NioEventLoopGroup
    try {
      //创建 Bootstrap
      val b = new Bootstrap
      //指定 EventLoopGroup 以处理客户端事件;需要适用于 NIO 的实现
      b.group(group)
        //适用于 NIO 传输的Channel 类型
        .channel(classOf[NioSocketChannel])
        //设置服务器的InetSocketAddress
        .remoteAddress(new InetSocketAddress(host, port))
        //在创建Channel时,向 ChannelPipeline中添加一个 EchoClientHandler实例
        .handler {
          new ChannelInitializer[SocketChannel]() {
            @throws[Exception]
            override def initChannel(ch: SocketChannel): Unit = {
              ch.pipeline.addLast(new EchoClientHandler)
            }
          }
        }
      //连接到远程节点,阻塞等待直到连接完成
      val f = b.connect.sync()
      //阻塞,直到Channel 关闭
      f.channel.closeFuture.sync()
    } finally {
      //关闭线程池并且释放所有的资源
      group.shutdownGracefully.sync()
    }
  }
} 
Example 16
Source File: NettyNioServer.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter4

import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.Unpooled
import io.netty.channel._
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioServerSocketChannel
import java.net.InetSocketAddress
import java.nio.charset.Charset


class NettyNioServer {
  @throws[Exception]
  def server(port: Int): Unit = {
    val buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")))
    //为非阻塞模式使用NioEventLoopGroup
    val group: EventLoopGroup = new NioEventLoopGroup
    try { //创建ServerBootstrap
      val b = new ServerBootstrap
      b.group(group)
        .channel(classOf[NioServerSocketChannel])
        .localAddress(new InetSocketAddress(port))
        //指定 ChannelInitializer,对于每个已接受的连接都调用它
        .childHandler {
          new ChannelInitializer[SocketChannel]() {
            @throws[Exception]
            override def initChannel(ch: SocketChannel): Unit = {
              ch.pipeline.addLast(new ChannelInboundHandlerAdapter() {
                @throws[Exception]
                override def channelActive(ctx: ChannelHandlerContext): Unit = {
                  //将消息写到客户端,并添加ChannelFutureListener,
                  //以便消息一被写完就关闭连接
                  ctx.writeAndFlush(buf.duplicate)
                    .addListener(ChannelFutureListener.CLOSE)
                }
              })
            }
          }
        }
      //绑定服务器以接受连接
      val f = b.bind.sync()
      f.channel.closeFuture.sync()
    } finally {
      //释放所有的资源
      group.shutdownGracefully.sync()
    }
  }
} 
Example 17
Source File: LogEventBroadcaster.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter13

import io.netty.bootstrap.Bootstrap
import io.netty.channel.{ ChannelOption, EventLoopGroup }
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioDatagramChannel
import java.io.File
import java.io.RandomAccessFile
import java.net.InetSocketAddress
import java.lang.{ Boolean ⇒ JBoolean }
import java.util.Objects

import scala.util.control.Breaks._


object LogEventBroadcaster {

  @throws[Exception]
  def main(args: Array[String]): Unit = {
    if (args.length != 2)
      throw new IllegalArgumentException

    //创建并启动一个新的 LogEventBroadcaster 的实例
    val broadcaster =
      new LogEventBroadcaster(new InetSocketAddress("255.255.255.255", args(0).toInt), new File(args(1)))

    try {
      broadcaster.run()
    } finally {
      broadcaster.stop()
    }
  }
}

class LogEventBroadcaster(address: InetSocketAddress, file: File) {
  val group: EventLoopGroup = new NioEventLoopGroup
  val bootstrap = new Bootstrap

  //引导该 NioDatagramChannel(无连接的)
  bootstrap
    .group(group)
    .channel(classOf[NioDatagramChannel])
    //设置 SO_BROADCAST 套接字选项
    .option[JBoolean](ChannelOption.SO_BROADCAST, true)
    .handler(new LogEventEncoder(address))

  @throws[Exception]
  def run(): Unit = { //绑定 Channel
    val ch = bootstrap.bind(0).sync.channel
    var pointer: Long = 0
    //启动主处理循环

    breakable {
      while (true) {
        val len = file.length
        if (len < pointer) { // file was reset
          //如果有必要,将文件指针设置到该文件的最后一个字节
          pointer = len
        } else if (len > pointer) { // Content was added
          val raf = new RandomAccessFile(file, "r")
          //设置当前的文件指针,以确保没有任何的旧日志被发送
          raf.seek(pointer)
          Iterator.continually(raf.readLine())
            .takeWhile(Objects.nonNull)
            .foreach { line ⇒
              ch.writeAndFlush(LogEvent(file.getAbsolutePath, line))
            }
          //存储其在文件中的当前位置
          pointer = raf.getFilePointer
          raf.close()
        }
        try {
          //休眠 1 秒,如果被中断,则退出循环;否则重新处理它
          Thread.sleep(1000)
        } catch {
          case e: InterruptedException ⇒
            Thread.interrupted
            break
        }
      }
    }
  }

  def stop(): Unit = {
    group.shutdownGracefully()
  }
} 
Example 18
Source File: LogEventMonitor.scala    From netty-in-action-scala   with Apache License 2.0 5 votes vote down vote up
package nia.chapter13

import io.netty.bootstrap.Bootstrap
import io.netty.channel._
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioDatagramChannel
import java.net.InetSocketAddress
import java.lang.{ Boolean ⇒ JBoolean }


object LogEventMonitor {

  @throws[Exception]
  def main(args: Array[String]): Unit = {
    if (args.length != 1)
      throw new IllegalArgumentException("Usage: LogEventMonitor <port>")

    //构造一个新的 LogEventMonitor
    val monitor = new LogEventMonitor(new InetSocketAddress(args(0).toInt))
    try {
      val channel = monitor.bind()
      println("LogEventMonitor running")
      channel.closeFuture.sync()
    } finally {
      monitor.stop()
    }
  }
}

class LogEventMonitor(address: InetSocketAddress) {
  val group: EventLoopGroup = new NioEventLoopGroup
  val bootstrap = new Bootstrap
  //引导该 NioDatagramChannel
  bootstrap.group(group)
    .channel(classOf[NioDatagramChannel])
    //设置套接字选项 SO_BROADCAST
    .option[JBoolean](ChannelOption.SO_BROADCAST, true)
    .handler(new ChannelInitializer[Channel]() {
      @throws[Exception]
      override protected def initChannel(channel: Channel): Unit = {
        val pipeline = channel.pipeline
        //将 LogEventDecoder 和 LogEventHandler 添加到 ChannelPipeline 中
        pipeline.addLast(new LogEventDecoder)
        pipeline.addLast(new LogEventHandler)
      }
    }).localAddress(address)

  def bind(): Channel = { //绑定 Channel。注意,DatagramChannel 是无连接的
    bootstrap.bind.syncUninterruptibly.channel
  }

  def stop(): Unit = {
    group.shutdownGracefully
  }
} 
Example 19
Source File: WoWChat.scala    From wowchat   with GNU General Public License v3.0 5 votes vote down vote up
package wowchat

import java.util.concurrent.{Executors, TimeUnit}

import wowchat.common.{CommonConnectionCallback, Global, ReconnectDelay, WowChatConfig}
import wowchat.discord.Discord
import wowchat.game.GameConnector
import wowchat.realm.{RealmConnectionCallback, RealmConnector}
import com.typesafe.scalalogging.StrictLogging
import io.netty.channel.nio.NioEventLoopGroup

import scala.io.Source

object WoWChat extends StrictLogging {

  private val RELEASE = "v1.3.3"

  def main(args: Array[String]): Unit = {
    logger.info(s"Running WoWChat - $RELEASE")
    val confFile = if (args.nonEmpty) {
      args(0)
    } else {
      logger.info("No configuration file supplied. Trying with default wowchat.conf.")
      "wowchat.conf"
    }
    Global.config = WowChatConfig(confFile)

    checkForNewVersion

    val gameConnectionController: CommonConnectionCallback = new CommonConnectionCallback {

      private val reconnectExecutor = Executors.newSingleThreadScheduledExecutor
      private val reconnectDelay = new ReconnectDelay

      override def connect: Unit = {
        Global.group = new NioEventLoopGroup

        val realmConnector = new RealmConnector(new RealmConnectionCallback {
          override def success(host: String, port: Int, realmName: String, realmId: Int, sessionKey: Array[Byte]): Unit = {
            gameConnect(host, port, realmName, realmId, sessionKey)
          }

          override def disconnected: Unit = doReconnect

          override def error: Unit = sys.exit(1)
        })

        realmConnector.connect
      }

      private def gameConnect(host: String, port: Int, realmName: String, realmId: Int, sessionKey: Array[Byte]): Unit = {
        new GameConnector(host, port, realmName, realmId, sessionKey, this).connect
      }

      override def connected: Unit = reconnectDelay.reset

      override def disconnected: Unit = doReconnect

      def doReconnect: Unit = {
        Global.group.shutdownGracefully()
        Global.discord.changeRealmStatus("Connecting...")
        val delay = reconnectDelay.getNext
        logger.info(s"Disconnected from server! Reconnecting in $delay seconds...")

        reconnectExecutor.schedule(new Runnable {
          override def run(): Unit = connect
        }, delay, TimeUnit.SECONDS)
      }
    }

    logger.info("Connecting to Discord...")
    Global.discord = new Discord(new CommonConnectionCallback {
      override def connected: Unit = gameConnectionController.connect

      override def error: Unit = sys.exit(1)
    })
  }

  private def checkForNewVersion = {
    // This is JSON, but I really just didn't want to import a full blown JSON library for one string.
    val data = Source.fromURL("https://api.github.com/repos/fjaros/wowchat/releases/latest").mkString
    val regex = "\"tag_name\":\"(.+?)\",".r
    val repoTagName = regex
      .findFirstMatchIn(data)
      .map(_.group(1))
      .getOrElse("NOT FOUND")

    if (repoTagName != RELEASE) {
      logger.error( "~~~ !!!                YOUR WoWChat VERSION IS OUT OF DATE                !!! ~~~")
      logger.error(s"~~~ !!!                     Current Version:  $RELEASE                      !!! ~~~")
      logger.error(s"~~~ !!!                     Repo    Version:  $repoTagName                      !!! ~~~")
      logger.error( "~~~ !!! RUN git pull OR GO TO https://github.com/fjaros/wowchat TO UPDATE !!! ~~~")
      logger.error( "~~~ !!!                YOUR WoWChat VERSION IS OUT OF DATE                !!! ~~~")
    }
  }
} 
Example 20
Source File: NettyServer.scala    From lila-ws   with GNU Affero General Public License v3.0 5 votes vote down vote up
package lila.ws
package netty

import com.typesafe.config.Config
import com.typesafe.scalalogging.Logger
import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.{ Channel, ChannelInitializer }
import io.netty.channel.epoll.{ EpollEventLoopGroup, EpollServerSocketChannel }
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.codec.http._
import scala.concurrent.ExecutionContext

final class NettyServer(
    clients: ClientSystem,
    router: Router,
    config: Config
)(implicit ec: ExecutionContext) {

  private val logger = Logger(getClass)

  def start(): Unit = {

    logger.info("Start")

    val port     = config.getInt("http.port")
    val useEpoll = config.getBoolean("netty.useEpoll")

    val bossGroup =
      if (useEpoll) new EpollEventLoopGroup(1)
      else new NioEventLoopGroup(1)
    val workerGroup =
      if (useEpoll) new EpollEventLoopGroup
      else new NioEventLoopGroup

    val channelClz =
      if (useEpoll) classOf[EpollServerSocketChannel]
      else classOf[NioServerSocketChannel]

    try {
      val boot = new ServerBootstrap
      boot
        .group(bossGroup, workerGroup)
        .channel(channelClz)
        .childHandler(new ChannelInitializer[Channel] {
          override def initChannel(ch: Channel): Unit = {
            val pipeline = ch.pipeline()
            pipeline.addLast(new HttpServerCodec)
            pipeline.addLast(new HttpObjectAggregator(4096))
            pipeline.addLast(new ProtocolHandler(clients, router))
            pipeline.addLast(new FrameHandler)
          }
        })

      val server = boot.bind(port).sync().channel()

      logger.info(s"Listening to $port")

      server.closeFuture().sync()

      logger.info(s"Closed $port")
    } finally {
      bossGroup.shutdownGracefully()
      workerGroup.shutdownGracefully()
    }

  }
} 
Example 21
Source File: WavesBlockchainClientBuilder.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.grpc.integration

import com.wavesplatform.dex.domain.utils.ScorexLogging
import com.wavesplatform.dex.grpc.integration.clients.{WavesBlockchainCachingClient, WavesBlockchainClient, WavesBlockchainGrpcAsyncClient}
import com.wavesplatform.dex.grpc.integration.settings.WavesBlockchainClientSettings
import io.grpc.ManagedChannel
import io.grpc.internal.DnsNameResolverProvider
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import monix.execution.Scheduler

import scala.concurrent.{ExecutionContext, Future}

object WavesBlockchainClientBuilder extends ScorexLogging {

  def async(wavesBlockchainClientSettings: WavesBlockchainClientSettings,
            monixScheduler: Scheduler,
            grpcExecutionContext: ExecutionContext): WavesBlockchainClient[Future] = {

    log.info(s"Building gRPC client for server: ${wavesBlockchainClientSettings.grpc.target}")

    val eventLoopGroup = new NioEventLoopGroup

    val channel: ManagedChannel =
      wavesBlockchainClientSettings.grpc.toNettyChannelBuilder
        .nameResolverFactory(new DnsNameResolverProvider)
        .executor((command: Runnable) => grpcExecutionContext.execute(command))
        .eventLoopGroup(eventLoopGroup)
        .channelType(classOf[NioSocketChannel])
        .usePlaintext()
        .build

    new WavesBlockchainCachingClient(
      new WavesBlockchainGrpcAsyncClient(eventLoopGroup, channel, monixScheduler)(grpcExecutionContext),
      wavesBlockchainClientSettings.defaultCachesExpiration,
      monixScheduler
    )(grpcExecutionContext)
  }
} 
Example 22
Source File: ParticipantSession.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.api.testtool.infrastructure.participant

import com.daml.ledger.api.testtool.infrastructure.LedgerServices
import com.daml.ledger.api.v1.ledger_identity_service.GetLedgerIdentityRequest
import com.daml.ledger.api.v1.transaction_service.GetLedgerEndRequest
import com.daml.timer.RetryStrategy
import io.grpc.ManagedChannel
import io.netty.channel.nio.NioEventLoopGroup
import org.slf4j.LoggerFactory

import scala.concurrent.duration.{DurationInt, SECONDS}
import scala.concurrent.{ExecutionContext, Future}

private[participant] final class ParticipantSession(
    val config: ParticipantSessionConfiguration,
    channel: ManagedChannel,
    eventLoopGroup: NioEventLoopGroup,
)(implicit val executionContext: ExecutionContext) {

  private[this] val logger = LoggerFactory.getLogger(classOf[ParticipantSession])

  private[this] val services: LedgerServices = new LedgerServices(channel)

  // The ledger identifier is retrieved only once when the participant session is created
  // Changing the ledger identifier during the execution of a session can result in unexpected consequences
  // The test tool is designed to run tests in an isolated environment but changing the
  // global state of the ledger breaks this assumption, no matter what
  private[this] val ledgerIdF =
    RetryStrategy.exponentialBackoff(10, 10.millis) { (attempt, wait) =>
      logger.debug(s"Fetching ledgerId to create context (attempt #$attempt, next one in $wait)...")
      services.identity.getLedgerIdentity(new GetLedgerIdentityRequest).map(_.ledgerId)
    }

  private[testtool] def createTestContext(
      endpointId: String,
      applicationId: String,
      identifierSuffix: String,
  ): Future[ParticipantTestContext] =
    for {
      ledgerId <- ledgerIdF
      end <- services.transaction.getLedgerEnd(new GetLedgerEndRequest(ledgerId)).map(_.getOffset)
    } yield
      new ParticipantTestContext(
        ledgerId,
        endpointId,
        applicationId,
        identifierSuffix,
        end,
        services,
        config.partyAllocation,
      )

  private[testtool] def close(): Unit = {
    logger.info(s"Disconnecting from participant at ${config.host}:${config.port}...")
    channel.shutdownNow()
    if (!channel.awaitTermination(10L, SECONDS)) {
      sys.error("Channel shutdown stuck. Unable to recover. Terminating.")
    }
    logger.info(s"Connection to participant at ${config.host}:${config.port} shut down.")
    if (!eventLoopGroup
        .shutdownGracefully(0, 0, SECONDS)
        .await(10L, SECONDS)) {
      sys.error("Unable to shutdown event loop. Unable to recover. Terminating.")
    }
    logger.info(s"Connection to participant at ${config.host}:${config.port} closed.")
  }
} 
Example 23
Source File: ParticipantSessionManager.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.api.testtool.infrastructure.participant

import io.grpc.netty.{NegotiationType, NettyChannelBuilder}
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.util.concurrent.DefaultThreadFactory
import org.slf4j.LoggerFactory

import scala.collection.concurrent.TrieMap
import scala.concurrent.{ExecutionContext, Future}

private[infrastructure] final class ParticipantSessionManager {

  private[this] val logger = LoggerFactory.getLogger(classOf[ParticipantSession])

  private[this] val channels = TrieMap.empty[ParticipantSessionConfiguration, ParticipantSession]

  @throws[RuntimeException]
  private def create(
      config: ParticipantSessionConfiguration,
  )(implicit ec: ExecutionContext): ParticipantSession = {
    logger.info(s"Connecting to participant at ${config.host}:${config.port}...")
    val threadFactoryPoolName = s"grpc-event-loop-${config.host}-${config.port}"
    val daemonThreads = false
    val threadFactory: DefaultThreadFactory =
      new DefaultThreadFactory(threadFactoryPoolName, daemonThreads)
    logger.info(
      s"gRPC thread factory instantiated with pool '$threadFactoryPoolName' (daemon threads: $daemonThreads)",
    )
    val threadCount = Runtime.getRuntime.availableProcessors
    val eventLoopGroup: NioEventLoopGroup =
      new NioEventLoopGroup(threadCount, threadFactory)
    logger.info(
      s"gRPC event loop thread group instantiated with $threadCount threads using pool '$threadFactoryPoolName'",
    )
    val managedChannelBuilder = NettyChannelBuilder
      .forAddress(config.host, config.port)
      .eventLoopGroup(eventLoopGroup)
      .channelType(classOf[NioSocketChannel])
      .directExecutor()
      .usePlaintext()
    for (ssl <- config.ssl; sslContext <- ssl.client) {
      logger.info("Setting up managed communication channel with transport security")
      managedChannelBuilder
        .useTransportSecurity()
        .sslContext(sslContext)
        .negotiationType(NegotiationType.TLS)
    }
    managedChannelBuilder.maxInboundMessageSize(10000000)
    val managedChannel = managedChannelBuilder.build()
    logger.info(s"Connection to participant at ${config.host}:${config.port}")
    new ParticipantSession(config, managedChannel, eventLoopGroup)
  }

  def getOrCreate(
      configuration: ParticipantSessionConfiguration,
  )(implicit ec: ExecutionContext): Future[ParticipantSession] =
    Future(channels.getOrElseUpdate(configuration, create(configuration)))

  def close(configuration: ParticipantSessionConfiguration): Unit =
    channels.get(configuration).foreach(_.close())

  def closeAll(): Unit =
    for ((_, session) <- channels) {
      session.close()
    }

}