A Simple Remote Chat application using Lift Comet and Akka Actor in Scala


If you are running an application and there are lot of chances for a huge traffic to come in future, a single server would not be capable to handle this.
In that case you would have two choices:
A) Replace existing server with an advance server with better configuration
B) Building a global node in the cluster to be used by other nodes.

We know that first option is not a permanent solution. So lets move to second option.

I have created a Login Application with Things To Do functionality using Lift in Scala.
In this application, I have added a chat module using LiftComet Actor and AkkaActor.

In the Chat Module, I have implemented cluster functionality, so that application could be accessed remotely.
So the concept is: there would be one Akka Actor on central server and this central akka actor would be used by other comet actors, whether they are on the same server or different server.

Since Lift has its own actor model, so I have created a bridge between LiftComet and Akka Actor, so that Akka actor would be able send message to comet, once comet has been set.

To learn bridging concept in deep, go here : http://riteofcoding.blogspot.in/2011/05/beyond-chat-lift-comet-and-akka.html

In this application, there is one controller

object CometAlertController extends Loggable {

This controller would give central actor reference, if exists, otherwise create a new central actor, if not exist. Here I have created a central actor with hard-coded configuration,
You can change this according to your application.

  private def getOrCreateActor: ActorRef = {
    try {
      val actorRef = GlobalActorSystem.getActorSystem.actorFor("akka://Node@" + hostAddress + ":3557" + "/user/Manager")
      val future = akka.pattern.ask(actorRef, Ping())
      // Use Await.result, if blocking is necessary
      // Use mapTo for non-blocking scenario
      val result = Await.result(future, timeout.duration).asInstanceOf[Ping]
      actorRef
    } catch {
      case e: TimeoutException =>
        createActor
    }
  }

As you can see in the above method, first controller will ping to central actor by sending a Ping message.
If actor exists, it would send a reply otherwise a TimeoutException would be thrown. If TimeoutException is caught in catch block, controller would create a new central actor.


  private def createActor = {
    val remoteSystem = ActorSystem("Node", ConfigFactory.load(configuration))
    val result = remoteSystem.actorOf(Props[AkkaAlertActor], "Manager")
    result
  }


  def getManager: ActorRef = getOrCreateActor

There is GlobalActorSystem.scala to create single actor system throughout the application.

For the chat module, there is Chat.scala, which is comet actor and AkkaAlertActor is Akka Actor.
The comet actor and akka actor would communicate with each other using BridgeActor, which works as a bridge between comet and akka.

Since In a remote application, actors would pass message throughout the network, so those messages must be serialized. To serialized those messages, I have implemented Akka-Kryo-Serialization.

How to run application:-

A) Clone code from https://github.com/romix/akka-kryo-serialization.

B) Run sbt compile publish-local

C) Now clone https://github.com/knoldus/Lift_UserLogin_Template

D) Run sbt ~container:start

How to test in remote environment:

A) Open a terminal and run sbt ~container:start.

B) Open build.sbt and change

port in container.Configuration := 8081

C) Open another terminal and run sbt ~container:start.

D) Register yourself and login and Enjoy chat.

You would be able to do chat remotely from different JVMs. Check and let me know your feedback. Your feedback would be highly appreciated.

About these ads

About ayushmishra2005

Ayush is the Sr. Software Consultant @ Knoldus Software LLP. In his 5 years of experience he has become developer with proven experience in architecting and developing web applications. Ayush has a Masters in Computer Application from U.P. Technical University, Ayush is a strong-willed and self-motivated professional who takes deep care in adhering to quality norms within projects. He is capable of managing challenging projects with remarkable deadline sensitivity without compromising code quality. .
This entry was posted in Agile, Akka, Java, LiftWeb, Scala, Web. Bookmark the permalink.

4 Responses to A Simple Remote Chat application using Lift Comet and Akka Actor in Scala

  1. Santo says:

    Regards
    Congratulations, your article is very interesting
    This topic is just what I was looking for
    Download your project to test it, but when compiling shows me the following error

    [error]
    ../Lift_UserLogin_Template/src/main/scala/code/lib/NettyPort.scala:15: class RemoteActorRefProvider in package remote cannot be accessed in package akka.remote
    [error] case r: RemoteActorRefProvider => r.transport.address.port.get.asInstanceOf[Int]
    [error] ^
    [error]
    ../Lift_UserLogin_Template/src/main/scala/code/lib/NettyPort.scala:15: value transport is not a member of akka.actor.ActorRefProvider
    [error] case r: RemoteActorRefProvider => r.transport.address.port.get.asInstanceOf[Int]
    [error] ^
    [error] two errors found

    How I can fix it?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s