Packages

  • package root

    Akka Actors to build Reactive TCP servers using Akka Actors

    Homepage: http://www.aspl.es/ronda
    Mailing list: http://lists.aspl.es/cgi-bin/mailman/listinfo/rondabridge

    Overview

    RondaBridge is a set of Akka Actors, written in Scala, that provides support to create TcpListeners and TcpConnections.

    Even though creating TcpClient software is supported, RondaBridge is more targeted to server side development for safe, scalable, concurrent and reactive TCP servers on top of Akka Actors system.

    RondaBridge aims to provide full support to create TcpListeners, including support for TLS, TLS SNI, multi-tenant configuration, and WebSocket.

    RondaBridge is OpenSource, released under the LGPL 2.1 is checked with an intense regression test that is expanded as much as we can. It is written using ScalaTest.

    We are using RondaBridge to provide Tcp support for MyQtt (https://www.aspl.es/myqtt).

    How to include RondaBridge

    Include the following into your build.sbt:

    lazy val rondaVersion = "0.11.127"
    libraryDependencies ++= Seq("es.aspl.ronda" %% "ronda-bridge" % rondaVersion)

    Or, download it from github and do a local install:

    >> git clone git://github.com/ASPLes/RondaBridge.gite
    >> cd RondaBridge
    >> sbt
    > compile
    > publishLocal

    ...and then include/import RondaBridge from your proyect as indicated above.

    How to create a TcpListener
    import ronda.tcp._
    class YourListenerActor extends Actor {
       // create a listener Actor
       val listener = TcpListener.create
       // bind tcp/4096 port
       listener ! BindPort (4096)
    
       ...rest of the actor class definition, including 'def receive'
    }
    How to get notifications for new incoming connections

    The actor that created the TcpListener, which is the master actor by that step, will get ronda.tcp.Api.NewConnection notification:

    class YourListenerActor extends Actor {
       // create a listener Actor
       val listener = TcpListener.create
       // bind tcp/4096 port
       listener ! BindPort (4096)
    
       // No need to send OnConnectionNew message because we have
       // created the listener and sent ronda.tcp.Api.BindPort
       // But, if we are a different actor wi will have to:
       // listener ! OnConnectionNew
    
       def receive = {
          case NewConnection (listener, connection, connFromAddress, connFromPort, listenerAddress, listenerPort) =>
            info (s"New connection received from ${connFromAddress}, local tcp connection actor: ${connection}")
       }
    }

    As you can see, a ronda.tcp.Api.NewConnection message along with new connection is received everytime a new incoming connection is received.

    Next steps

    Once created a TcpListener or a TcpConnection, use Api messages available to interact with these actors, to configure them and to make them do the useful work.

    Definition Classes
    root
  • package ronda
    Definition Classes
    root
  • package tcp
    Definition Classes
    ronda
  • Api
  • TcpConnection
  • TcpConnectionReader
  • TcpListener

object TcpConnection

Static functions to manage ronda.tcp.TcpConnection Actors

How to create a client/initiator tcp connection

import ronda.tcp.Api._
import ronda.tcp._

// create an actor connection (the following happens inside an Akka actor)
// create connection reference passing implict reference to context.system : ActorSystem,
// if you do not have it defined. You can also do import context.system
var connActor : ActorRef = TcpConnection.create (context.system)

// then, request this actor to connect to selected destination
connActor ! ConnectTo ('destination.host', 29010)

Once the connection failed or succeeded to connect, the actor that created it (which is considered the master actor), will receive a ronda.tcp.Api.ConnectToResult notification, reporting if the connection was successful or not.

Receiving data

From that point, the master actor that created the client connection will receive ronda.tcp.Api.BytesReceived messages as incoming bytes are read.

Sending data

In the case an actor wants to to write/send bytes to the connection, use ronda.tcp.Api.SendBytes or ronda.tcp.Api.SendUTF8String.

Server side TcpConnection : actor for incoming connections

In the case you created a TcpListener$ actor, a ronda.tcp.Api.NewConnection notification is received for every new incoming connection accepted on this listener.

Inside that notification is reported a reference to the TcpConnection accepted.

That TcpConnection$ will work in essense as a client side connection but flagged with ListenerRole.

Is there any difference between client or server TcpConnection?

Apart from role, both are full duplex TcpConnections that accepts same Api messages, like ronda.tcp.Api.BytesReceived, ronda.tcp.Api.SendBytes, etc...

Next steps

Now use the API to send and receive API messages from/to TcpConnection Actor to implement the functionality required.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. TcpConnection
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. trait ConnectionRole extends AnyRef

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  6. def create(role: ConnectionRole)(implicit system: ActorSystem): ActorRef

    Creates a new unconnected TcpConnection actor.

  7. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  8. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  9. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  10. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  11. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  12. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  13. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  14. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  15. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  16. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  17. def toString(): String
    Definition Classes
    AnyRef → Any
  18. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  19. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  20. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  21. object InitiatorRole extends ConnectionRole with Product with Serializable
  22. object ListenerRole extends ConnectionRole with Product with Serializable

Inherited from AnyRef

Inherited from Any

Ungrouped