akka.io.Tcp Scala Examples

The following examples show how to use akka.io.Tcp. 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: ChaosActorInterface.scala    From eventuate-chaos   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.chaos

import akka.actor.ActorRef
import akka.io.Tcp
import akka.util.ByteString
import akka.pattern.ask
import akka.util.Timeout
import com.rbmhtechnology.eventuate.chaos.ChaosActorInterface.HealthCheckResult
import com.rbmhtechnology.eventuate.chaos.ChaosActorInterface.HealthCheck

import scala.concurrent.duration._
import scala.util.Failure
import scala.util.Success


object ChaosActorInterface {
  case class HealthCheck(requester: ActorRef)
  case class HealthCheckResult(state: Int, requester: ActorRef)
}

class ChaosActorInterface(chaosActor: ActorRef) extends ChaosInterface {
  implicit val timeout = Timeout(1.seconds)

  def handleCommand = {
    case ("persist", None, recv) =>
      val check = HealthCheck(recv)

      (chaosActor ? check).mapTo[HealthCheckResult] onComplete {
        case Success(result) =>
          result.requester ! Tcp.Write(ByteString(result.state.toString))
          result.requester ! Tcp.Close
        case Failure(e) =>
          recv ! Tcp.Close
      }
  }
} 
Example 2
Source File: ChaosInterface.scala    From eventuate-chaos   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.chaos

import java.net.InetSocketAddress

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorRef
import akka.io.IO
import akka.io.Tcp
import akka.util.ByteString

abstract class ChaosInterface extends Actor with ActorLogging {
  val port = 8080
  val endpoint = new InetSocketAddress(port)
  val command = """(?s)(\w+)\s+(\d+).*""".r

  implicit val ec = context.dispatcher

  IO(Tcp)(context.system) ! Tcp.Bind(self, endpoint)

  println(s"Now listening on port $port")

  def handleCommand: PartialFunction[(String, Option[Int], ActorRef), Unit]

  protected def reply(message: String, receiver: ActorRef) = {
    receiver ! Tcp.Write(ByteString(message))
    receiver ! Tcp.Close
  }

  protected def closeOnError(receiver: ActorRef): PartialFunction[Throwable, Unit] = {
    case err: Throwable =>
      receiver ! Tcp.Close
  }

  def receive: Receive = {
    case Tcp.Connected(remote, _) =>
      sender ! Tcp.Register(self)

    case Tcp.Received(bs) =>
      val content = bs.utf8String

      content match {
        case command(c, value) if handleCommand.isDefinedAt(c, Some(value.toInt), sender) =>
          handleCommand(c, Some(value.toInt), sender)
        case c if c.startsWith("quit") =>
          context.system.terminate()
        case c if handleCommand.isDefinedAt(c, None, sender) =>
          handleCommand(c, None, sender)
        case _ =>
          sender ! Tcp.Close
      }

    case Tcp.Closed =>
    case Tcp.PeerClosed =>
  }
} 
Example 3
Source File: ServerActor.scala    From mantis   with Apache License 2.0 5 votes vote down vote up
package io.iohk.ethereum.network

import java.net.InetSocketAddress

import akka.actor.{Actor, ActorLogging, ActorRef, Props}
import akka.agent.Agent
import akka.io.Tcp.{Bind, Bound, CommandFailed, Connected}
import akka.io.{IO, Tcp}
import io.iohk.ethereum.utils.{NodeStatus, ServerStatus}
import org.spongycastle.util.encoders.Hex

class ServerActor(nodeStatusHolder: Agent[NodeStatus], peerManager: ActorRef) extends Actor with ActorLogging {

  import ServerActor._
  import context.system

  override def receive: Receive = {
    case StartServer(address) =>
      IO(Tcp) ! Bind(self, address)
      context become waitingForBindingResult
  }

  def waitingForBindingResult: Receive = {
    case Bound(localAddress) =>
      val nodeStatus = nodeStatusHolder()
      log.info("Listening on {}", localAddress)
      log.info("Node address: enode://{}@{}:{}",
        Hex.toHexString(nodeStatus.nodeId),
        getHostName(localAddress.getAddress),
        localAddress.getPort)
      nodeStatusHolder.send(_.copy(serverStatus = ServerStatus.Listening(localAddress)))
      context become listening

    case CommandFailed(b: Bind) =>
      log.warning("Binding to {} failed", b.localAddress)
      context stop self
  }

  def listening: Receive = {
    case Connected(remoteAddress, _) =>
      val connection = sender()
      peerManager ! PeerManagerActor.HandlePeerConnection(connection, remoteAddress)
  }
}

object ServerActor {
  def props(nodeStatusHolder: Agent[NodeStatus], peerManager: ActorRef): Props =
    Props(new ServerActor(nodeStatusHolder, peerManager))

  case class StartServer(address: InetSocketAddress)
} 
Example 4
Source File: SBTBotTestRunner.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
package org.perftester.sbtbot

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.io.{IO, Tcp}
import akka.testkit.TestProbe
import ammonite.ops.Path
import org.perftester.sbtbot.SBTBot.{ExecuteTask, SBTBotReady, TaskResult}

object SBTBotTestRunner {

  
  def run(testDir: Path,
          programArgs: List[String],
          jvmArgs: List[String],
          repeats: Int,
          commands: List[String],
          debugging: Boolean): Unit = {
    implicit val actorSystem: ActorSystem = ActorSystem("test")

    val manager = IO(Tcp)

    val proxy = TestProbe()
    val parent = actorSystem.actorOf(Props(new Actor {
      val child: ActorRef =
        context.actorOf(SBTBot.props(testDir, programArgs, jvmArgs), "sbtbot")

      def receive: Receive = {
        case x if sender == child => proxy.ref forward x
        case x                    => child forward x
      }
    }))

    import scala.concurrent.duration._

    try {
      proxy.expectMsg(600.seconds, SBTBotReady)
      println("SBT Bot ready - starting run")
      val timeout = if (debugging) 20 minutes else 40 minutes

      for (i <- 1 to repeats) {
        implicit val sender: ActorRef = proxy.ref
        commands.zipWithIndex foreach {
          case (cmd, idx) =>
            println(
              s"--------------- $cmd - iteration  $i/$repeats -------------------------------")
            parent ! ExecuteTask(s"$idx", cmd)
            proxy.expectMsgClass(timeout, classOf[TaskResult])
//            Thread.sleep(5000)
        }
      }

      println("---------------Finished --------------------------------")
    } finally {
      actorSystem.terminate()
    }
  }
} 
Example 5
Source File: Server.scala    From mqttd   with MIT License 5 votes vote down vote up
package plantae.citrus.mqtt.actors.connection

import java.net.InetSocketAddress

import akka.actor.{Actor, ActorLogging, Props}
import akka.io.{IO, Tcp}
import plantae.citrus.mqtt.actors.SystemRoot

class Server extends Actor with ActorLogging {

  import Tcp._
  import context.system

  IO(Tcp) ! Bind(self, new InetSocketAddress(
    SystemRoot.config.getString("mqtt.broker.hostname"),
    SystemRoot.config.getInt("mqtt.broker.port"))
    , backlog = 1023)

  def receive = {
    case Bound(localAddress) =>

    case CommandFailed(_: Bind) =>
      log.error("bind failure")
      context stop self

    case Connected(remote, local) =>
      log.info("new connection" + remote)
      sender ! Register(context.actorOf(Props(classOf[PacketBridge], sender)))
  }
} 
Example 6
Source File: ClientTest.scala    From bitcoin-s-spv-node   with MIT License 5 votes vote down vote up
package org.bitcoins.spvnode.networking

import java.net.{InetSocketAddress, ServerSocket}

import akka.actor.ActorSystem
import akka.io.{Inet, Tcp}
import akka.testkit.{ImplicitSender, TestActorRef, TestKit, TestProbe}
import org.bitcoins.core.config.TestNet3
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
import org.bitcoins.spvnode.messages.control.VersionMessage
import org.bitcoins.spvnode.messages.{NetworkPayload, VersionMessage}
import org.bitcoins.spvnode.util.BitcoinSpvNodeUtil
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, FlatSpecLike, MustMatchers}

import scala.concurrent.duration._
import scala.util.Try

class ClientTest extends TestKit(ActorSystem("ClientTest")) with FlatSpecLike
  with MustMatchers with ImplicitSender
  with BeforeAndAfter with BeforeAndAfterAll with BitcoinSLogger {

  "Client" must "connect to a node on the bitcoin network, " +
    "send a version message to a peer on the network and receive a version message back, then close that connection" in {
    val probe = TestProbe()

    val client = TestActorRef(Client.props,probe.ref)

    val remote = new InetSocketAddress(TestNet3.dnsSeeds(0), TestNet3.port)
    val randomPort = 23521
    //random port
    client ! Tcp.Connect(remote, Some(new InetSocketAddress(randomPort)))

    //val bound : Tcp.Bound = probe.expectMsgType[Tcp.Bound]
    val conn : Tcp.Connected = probe.expectMsgType[Tcp.Connected]

    //make sure the socket is currently bound
    Try(new ServerSocket(randomPort)).isSuccess must be (false)
    client ! Tcp.Abort
    val confirmedClosed = probe.expectMsg(Tcp.Aborted)

    //make sure the port is now available
    val boundSocket = Try(new ServerSocket(randomPort))
    boundSocket.isSuccess must be (true)

    boundSocket.get.close()

  }

  it must "bind connect to two nodes on one port" in {
    //NOTE if this test case fails it is more than likely because one of the two dns seeds
    //below is offline
    val remote1 = new InetSocketAddress(TestNet3.dnsSeeds(0), TestNet3.port)
    val remote2 = new InetSocketAddress(TestNet3.dnsSeeds(2), TestNet3.port)

    val probe1 = TestProbe()
    val probe2 = TestProbe()


    val client1 = TestActorRef(Client.props, probe1.ref)
    val client2 = TestActorRef(Client.props, probe2.ref)

    val local1 = new InetSocketAddress(TestNet3.port)
    val options = List(Inet.SO.ReuseAddress(true))
    client1 ! Tcp.Connect(remote1,Some(local1),options)


    probe1.expectMsgType[Tcp.Connected]
    client1 ! Tcp.Abort

    val local2 = new InetSocketAddress(TestNet3.port)
    client2 ! Tcp.Connect(remote2,Some(local2),options)
    probe2.expectMsgType[Tcp.Connected](5.seconds)
    client2 ! Tcp.Abort
  }

  override def afterAll: Unit = {
    TestKit.shutdownActorSystem(system)
  }


} 
Example 7
Source File: Controller.scala    From eclair   with Apache License 2.0 5 votes vote down vote up
package fr.acinq.eclair.tor

import java.net.InetSocketAddress

import akka.actor.{Actor, ActorLogging, OneForOneStrategy, Props, SupervisorStrategy, Terminated}
import akka.io.{IO, Tcp}
import akka.util.ByteString

import scala.concurrent.ExecutionContext


class Controller(address: InetSocketAddress, protocolHandlerProps: Props)
                (implicit ec: ExecutionContext = ExecutionContext.global) extends Actor with ActorLogging {

  import Controller._
  import Tcp._
  import context.system

  IO(Tcp) ! Connect(address)

  def receive = {
    case e@CommandFailed(_: Connect) =>
      e.cause match {
        case Some(ex) => log.error(ex, "Cannot connect")
        case _ => log.error("Cannot connect")
      }
      context stop self
    case c: Connected =>
      val protocolHandler = context actorOf protocolHandlerProps
      protocolHandler ! c
      val connection = sender()
      connection ! Register(self)
      context watch connection
      context become {
        case data: ByteString =>
          connection ! Write(data)
        case CommandFailed(w: Write) =>
          // O/S buffer was full
          protocolHandler ! SendFailed
          log.error("Tor command failed")
        case Received(data) =>
          protocolHandler ! data
        case _: ConnectionClosed =>
          context stop self
        case Terminated(actor) if actor == connection =>
          context stop self
      }
  }

  // we should not restart a failing tor session
  override val supervisorStrategy = OneForOneStrategy(loggingEnabled = true) { case _ => SupervisorStrategy.Escalate }

}

object Controller {
  def props(address: InetSocketAddress, protocolHandlerProps: Props)(implicit ec: ExecutionContext = ExecutionContext.global) =
    Props(new Controller(address, protocolHandlerProps))

  case object SendFailed

} 
Example 8
Source File: Server.scala    From eclair   with Apache License 2.0 5 votes vote down vote up
package fr.acinq.eclair.io

import java.net.InetSocketAddress

import akka.Done
import akka.actor.{Actor, ActorRef, DiagnosticActorLogging, Props}
import akka.event.Logging.MDC
import akka.io.Tcp.SO.KeepAlive
import akka.io.{IO, Tcp}
import fr.acinq.eclair.Logs.LogCategory
import fr.acinq.eclair.{Logs, NodeParams}

import scala.concurrent.Promise


class Server(nodeParams: NodeParams, switchboard: ActorRef, router: ActorRef, address: InetSocketAddress, bound: Option[Promise[Done]] = None) extends Actor with DiagnosticActorLogging {

  import Tcp._
  import context.system

  IO(Tcp) ! Bind(self, address, options = KeepAlive(true) :: Nil, pullMode = true)

  def receive() = {
    case Bound(localAddress) =>
      bound.map(_.success(Done))
      log.info(s"bound on $localAddress")
      // Accept connections one by one
      sender() ! ResumeAccepting(batchSize = 1)
      context.become(listening(sender()))

    case CommandFailed(_: Bind) =>
      bound.map(_.failure(new RuntimeException("TCP bind failed")))
      context stop self
  }

  def listening(listener: ActorRef): Receive = {
    case Connected(remote, _) =>
      log.info(s"connected to $remote")
      val connection = sender
      val peerConnection = context.actorOf(PeerConnection.props(
        nodeParams = nodeParams,
        switchboard = switchboard,
        router = router
      ))
      peerConnection ! PeerConnection.PendingAuth(connection, remoteNodeId_opt = None, address = remote, origin_opt = None)
      listener ! ResumeAccepting(batchSize = 1)
  }

  override def mdc(currentMessage: Any): MDC = Logs.mdc(Some(LogCategory.CONNECTION))
}

object Server {

  def props(nodeParams: NodeParams, switchboard: ActorRef, router: ActorRef, address: InetSocketAddress, bound: Option[Promise[Done]] = None): Props = Props(new Server(nodeParams, switchboard, router: ActorRef, address, bound))

} 
Example 9
Source File: ShieldActor.scala    From shield   with MIT License 5 votes vote down vote up
package shield.actors

import akka.actor._
import akka.io.{IO, Tcp}
import shield.config.{DomainSettings, Settings}
import shield.metrics.Instrumented
import shield.routing._
import spray.can.Http
import spray.http._

// todo: verify how Spray handles HEAD requests
// todo: 412 Precondition Failed support
// todo: 417 Expectation Failed support
// todo: does spray automatically handle `505 HTTP Version Not Supported`?
// todo: periodically inspect a response to validate it's compliance with the documented swagger schema
object ShieldActor {
  def props() : Props = Props(new ShieldActor())
}

object ShieldActorMsgs {
  case class DomainsUpdated(domains: Map[String, DomainSettings])
  case class RouterUpdated(domain: String, router: RequestRouter)
  case class ListenersUpdated(domain: String, listeners: collection.Map[String, ActorRef])
}
class ShieldActor() extends Actor with ActorLogging with RestartLogging with Instrumented {
  // todo: integrate spray's service statistics into this
  import context.system
  val settings = Settings(context.system)

  val domainWatcher = context.actorOf(Props(settings.DomainWatcher), "domain-watcher")
  var domains = Map[String, DomainSettings]()

  var defaultRouter = buildDefaultRouter()
  var routers = Map[String, RequestRouter]()
  var listeners = Map[String,  collection.Map[String, ActorRef]]()

  // start a new HTTP server on port 8080 with our service actor as the handler
  IO(Http) ! Http.Bind(self, interface = "0.0.0.0", port = settings.Port)

  val connectionCounter = metrics.counter("open-connections")
  val requestMeter = metrics.meter("requests")
  val connectionOpenMeter = metrics.meter("connection-open")
  val connectionCloseMeter = metrics.meter("connection-close")


  def receive: Receive = {
    // todo: graceful shutdown (save bound's sender for later)
    case Http.Bound(addr) =>
      log.info("Server successfully bound to {}", addr)

    case Http.CommandFailed(cmd) =>
      log.error("Failed to bind the server: cmd={}", cmd)
      system.shutdown()

    case _ : Tcp.Connected =>
      connectionCounter += 1
      connectionOpenMeter.mark()
      sender ! Tcp.Register(self)
    case _ : Tcp.ConnectionClosed =>
      connectionCounter -= 1
      connectionCloseMeter.mark()

    case request: HttpRequest =>
      requestMeter.mark()
      val domain = request.header[HttpHeaders.Host].map(_.host).getOrElse(request.uri.authority.host.address)
      val destination = for {
        location <- Some(settings.DefaultServiceLocation)
        domainSettings <- domains.get(domain)
        router <- routers.get(domain)
        listeners <- listeners.get(domain)
      } yield (location, domainSettings.IgnoreExtensions, router, listeners)
      val (location, ignoredExtensions, router, listenerList) = destination.getOrElse(settings.DefaultServiceLocation, Set[String](), defaultRouter, collection.Map[String, ActorRef]())

      // todo: profiling optimization: destroying these actors is expensive.  Make a resizable pool
      context.actorOf(RequestProcessor.props(router, listenerList, sender(), location, ignoredExtensions)) ! request

    case du: ShieldActorMsgs.DomainsUpdated =>
      val newDomains = du.domains.keySet.diff(domains.keySet)
      for (d <- newDomains) {
        routers += d -> BootstrapRouter.router(settings.DefaultServiceLocation, settings.LocalServiceName, settings.HealthcheckTemplate)
        listeners += d -> collection.Map[String, ActorRef]()
      }
      val removedDomains = domains.keySet.diff(du.domains.keySet)
      for (d <- removedDomains) {
        routers -= d
        listeners -= d
      }
      domains = du.domains
      defaultRouter = buildDefaultRouter()

    case ru: ShieldActorMsgs.RouterUpdated => routers += ru.domain -> ru.router
    case lu: ShieldActorMsgs.ListenersUpdated => listeners += lu.domain -> lu.listeners
  }

  private def buildDefaultRouter() : RequestRouter = {
    BootstrapRouter.defaultRouter(settings.DefaultServiceLocation, settings.LocalServiceName, settings.HealthcheckTemplate, domains.keySet)
  }
} 
Example 10
Source File: TelnetClientActor.scala    From asura   with MIT License 5 votes vote down vote up
package asura.dubbo.actor

import java.net.InetSocketAddress

import akka.actor.{ActorRef, Props, Status}
import akka.io.{IO, Tcp}
import akka.util.ByteString
import asura.common.actor.BaseActor
import asura.common.util.LogUtils
import asura.dubbo.DubboConfig

class TelnetClientActor(remote: InetSocketAddress, listener: ActorRef) extends BaseActor {

  import Tcp._
  import context.system

  IO(Tcp) ! Connect(remote)

  override def receive: Receive = {
    case CommandFailed(_: Connect) =>
      listener ! ByteString(s"${TelnetClientActor.MSG_CONNECT_TO} ${remote.getAddress.getHostAddress}:${remote.getPort} ${TelnetClientActor.MSG_FAIL}\r\n")
      context stop self
    case Connected(remote, local) =>
      log.debug(s"local address: ${local}, remote address: ${remote}")
      listener ! ByteString(s"${TelnetClientActor.MSG_CONNECT_TO} ${remote.getAddress.getHostAddress}:${remote.getPort} ${TelnetClientActor.MSG_SUCCESS}\r\n")
      val remoteConnection = sender()
      remoteConnection ! Register(self)
      context.become {
        case data: ByteString =>
          remoteConnection ! Write(data)
        case CommandFailed(_: Write) =>
          listener ! ByteString("write failed\r\n")
        case Received(data) =>
          listener ! data
        case TelnetClientActor.CMD_CLOSE =>
          remoteConnection ! Close
        case _: ConnectionClosed =>
          listener ! ByteString(s"connection to ${remote.getAddress.getHostAddress}:${remote.getPort} closed\r\n")
          context stop self
      }
    case Status.Failure(t) =>
      val stackTrace = LogUtils.stackTraceToString(t)
      log.warning(stackTrace)
      listener ! t.getMessage
      context stop self
  }

  override def postStop(): Unit = log.debug(s"${self.path} stopped")
}


object TelnetClientActor {

  val CMD_CLOSE = "close"
  val MSG_CONNECT_TO = "connect to"
  val MSG_SUCCESS = "success"
  val MSG_FAIL = "fail"

  def props(remote: InetSocketAddress, replies: ActorRef) = {
    Props(new TelnetClientActor(remote, replies))
  }

  def props(address: String, port: Int, replies: ActorRef) = {
    Props(
      new TelnetClientActor(
        new InetSocketAddress(address, if (port > 0) port else DubboConfig.DEFAULT_PORT),
        replies
      )
    )
  }
}