Lightbend Activator

Reactive Snake - Akka Actor and Web Socket Example

Activator will be EOL-ed on May 24, 2017.

We’re making it easier and simpler for developers to get started with Lightbend technologies. This unfortunately means that future releases of Play, Akka and Scala will no longer include Activator support, and Lightbend’s Activator server will be decommissioned by the end of 2017. Instead of supporting Activator to create and set up development projects, we'll be supporting standard Giter8 templates for sbt users and Maven archetypes for Maven users. So going forward,

To create new Lightbend projects

Instead of using the Activator command, make sure you have sbt 0.13.13 (or higher), and use the “sbt new” command, providing the name of the template. For example, “$ sbt new akka/hello-akka.g8”. You can find a list of templates here.

Also, as a convenience, the Lightbend Project Starter allows you to quickly create a variety of example projects that you just unzip and run.

To create new templates

If you want to create new templates, you can now do that in Giter8.

To migrate templates from Activator to Giter8

If you created Activator templates in the past, please consider migrating them to Giter8 with this simple process.

Reactive Snake - Akka Actor and Web Socket Example

June 7, 2014
akka websocket scaladays2014 play scala

This template demonstrates use of actors and websockets in play, using the famous snake game as an example.

How to get "Reactive Snake - Akka Actor and Web Socket Example" on your computer

There are several ways to get this template.

Option 1: Choose snakeyard in the Lightbend Activator UI.

Already have Lightbend Activator (get it here)? Launch the UI then search for snakeyard in the list of templates.

Option 2: Download the snakeyard project as a zip archive

If you haven't installed Activator, you can get the code by downloading the template bundle for snakeyard.

  1. Download the Template Bundle for "Reactive Snake - Akka Actor and Web Socket Example"
  2. Extract the downloaded zip file to your system
  3. The bundle includes a small bootstrap script that can start Activator. To start Lightbend Activator's UI:

    In your File Explorer, navigate into the directory that the template was extracted to, right-click on the file named "activator.bat", then select "Open", and if prompted with a warning, click to continue:

    Or from a command line:

     C:\Users\typesafe\snakeyard> activator ui 
    This will start Lightbend Activator and open this template in your browser.

Option 3: Create a snakeyard project from the command line

If you have Lightbend Activator, use its command line mode to create a new project from this template. Type activator new PROJECTNAME snakeyard on the command line.

Option 4: View the template source

The creator of this template maintains it at

Option 5: Preview the tutorial below

We've included the text of this template's tutorial below, but it may work better if you view it inside Activator on your computer. Activator tutorials are often designed to be interactive.

Preview the tutorial

Reactive Snake Activator Template

This template uses the popular snake game as an inbrowser app to demonstrate Akka actors using web sockets. Actor Model gives a very natural representation of domain logic by resembling real objects and its interactions. I think this makes the code clearer and easy to read. SnakePool represents a bundle of snakes, it can create snakes and upon game over kill them all. Snake represents a single snake, having cell coordinates as an internal state. Snake can be started, moved (Up, Down, Left or Right) or eat apples. All snakes strive for the one apple. Currently Apple can be created or is eaten. When apple is eaten, a new one is created. The application can be easily extended with more apples, since Apple is also an actor. Snakes and apple need to send data to browser via web socket. In order to have web socket writing encapsulated we have WebSocketChannel which handles Send messages. WebSocketChannel actor helps unit test verification for Snake and Apple unit tests.
All browser requests are handled by SnakeController.
More than one snake pool can run concurrently, if you want to see the power of concurrency and actors, you may test application on two browser instances.


The Actor Model represents objects and their interactions, resembling human organisations. Actors have addresses on which messages can be send by tell or ! method. Every Actor class must inherit trait and implement receive method where message handling happens.

class SnakePool(webSocketChannel: ActorRef) extends Actor {
  def receive = {
Creating Actors

context.actorOf(Snake.props(apple, snakeName, webSocketChannel), snakeName)
Method actorOf accepts Akka.props but parameters to actor's constructor can be passed easily by defining a helper function in actor's companion object:

object SnakePool {
  def props(webSocketChannel: ActorRef): Props = Props(new SnakePool(webSocketChannel))
Then actor creation looks like this:

object SnakeController extends Controller {
  def startGame = {
	val webSocketChannel = Akka.system.actorOf(WebSocketChannel.props(channel))
	val snakePool = Akka.system.actorOf(SnakePool.props(webSocketChannel))
Stopping Actors

There are several ways to stop an actor. In the example application asynchronous stop is used by sending PoisonPill message. The following line of code show how snake dies when eats its tale

self ! PoisonPill

Note that all snakes and the pool die when at least one snake dies. This is covered by SnakePool supervisor who listens for Terminated child messages after register snakes with DeathWatch.

case NewSnake(snakeName) => {
  val snake = context.actorOf(Snake.props(apple, snakeName, webSocketChannel), snakeName)
  snake ! Start
  snakes += (snakeName -> snake)
case t: Terminated => self ! PoisonPill
The postStop hook is invoked after an actor is fully stopped. This enables cleaning up of resources. In the example application SnakePool has reference to all snakes in the pool and upon game over, pool is removed and it cleans all snakes corresponding to this pool.

class SnakePool(webSocketChannel: ActorRef) extends Actor {
  var snakes = Map.empty[String, ActorRef]
  override def postStop() { => snakeByName._2 ! Kill)

Supervision describes a dependency relationship between actors: the supervisor delegates tasks to subordinates and therefore must respond to their failures. Here you can find information about supervision. The following code will stop all snakes in case snake throws unhandled exception.

class SnakePool(webSocketChannel: ActorRef) extends Actor {
	override val supervisorStrategy = AllForOneStrategy() {
		case anyException => Stop //if something happens to one snake, kill them all
The AllForOneStrategy is applicable in cases where the ensemble of children has such tight dependencies among them, that a failure of one child affects the function of the others.

Fetch an Actor

actorSelection is used to fetch already created snake pool by name. Its argument is actor path Akka.system.actorSelection("/user/" + snakePoolName)

Sending a message

snakePool ! NewSnake(snakeName)
More information on actors

Web Sockets

Web Sockets is a next-generation bidirectional communication technology for web applications which operates over a single socket and is exposed via a JavaScript interface in HTML 5 complaint browsers.

Creating a web socket example

function startGame(row, col) {
	 for ( i = 1; i <= row*col; i++) {		  
	 websocket = new WebSocket(wsUri + "startgame");

	 websocket.onopen = function (evt) {
		 onOpen(evt, snake_name)
	 websocket.onclose = function (evt) {
		 onClose(evt, snake_name)
	 websocket.onmessage = function (evt) {
		 onMessage(evt, snake_name)

object SnakeController extends Controller {
  def startGame = WebSocket.using[String] { request =>
	val (out, channel) = Concurrent.broadcast[String]
	val webSocketChannel = Akka.system.actorOf(WebSocketChannel.props(channel))
	val snakePool = Akka.system.actorOf(SnakePool.props(webSocketChannel))
	val in = Iteratee.foreach[String] { msg => if (msg == "GET POOL") channel.push("POOL:" +; }
	(in, out)
In order to have startGame function exposed you need to change routes file accordingly

GET   /startgame         snakeyard.SnakeController.startGame
Send and receive messages

Once you get a Web Socket connection with the web server, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler. In the example application when socket is open, browser send get pool command and pool name is returned. Pool is keept for future requests, for example to add or move a snake in the pool.

Send a message to server

function onOpen(evt, snake_name) {
	 websocket.send("GET POOL");
Receive a message from client

In relation to the snippet above, when get pool request is sent, pool name is returned

val in = Iteratee.foreach[String] { msg => if (msg == "GET POOL") channel.push("POOL:" +; }
Send message from server

WebSocketChannel keeps a reference to web socket and sends information when Send message is triggered

class WebSocketChannel(channel: Concurrent.Channel[String]) extends Actor {
	def receive = {
	  case Send(data) => channel.push(data)
Receive a message from server

When information from server is received onMessage is triggered. In the example application onMessage changes background colour of related cells accordingly.

function onMessage(evt, snake_name) {
	 if ("POOL:", 0) === 0) { snake_pool ="POOL:","");}
	 else if ("APPLE:", 0) === 0) { apple("APPLE:",""));}
	 else if ( == "Game Over") { 
		 writeToScreen("GAME OVER");
	 else if ( > 0) on(;
	 else off(Math.abs(;

Testing Actors

Tests can only verify externally observable effects. The example bellow show how the asynchronous messages are verified using remove-controlled actor TestProbe.

class SnakeTest extends TestKit(ActorSystem("SnakeTest"))
  with FunSpec {

  describe("Snake Actor Test") {
	it("given new snake when started starts to the right, from thee first cell on the first line") {
	  val apple = TestProbe()
	  val channel = TestProbe()
	  val snakeName = "testSnake1"
	  val snake = system.actorOf(Snake.props(apple.ref, snakeName, channel.ref), snakeName)
	  snake ! Start
Using multiple test probes, you can verify conversation content and order of multiple actors. The second example uses mockito mock object and test probe. It shows you how you can inject mocked behaviour in an actor. In order to control what numbers are random in the test, random instance is passed to Apple actor. In a test environment instead of real instance it can be mocked.

class AppleTest extends TestKit(ActorSystem("AppleTest"))
  with FunSpec
  with Mockito {

  describe("Apple Test") {
 it("When Eat coordinate != apple, then StayHungry") {
	  val client = TestProbe()
	  val channel = TestProbe()
	  val appleName = "testApple3"
	  val random = mock[Random]
	  random.nextInt(SnakePoolConfig.row * SnakePoolConfig.col - 1) returns 123
	  val apple = system.actorOf(Apple.props(random, channel.ref), appleName)

	  apple ! NewApple
	  client.send(apple, Eat(135)) 
You can find more information on testing actors here

Welcome to the Lightbend Enterprise Suite

You are excited about Reactive applications. And you want to build, manage and monitor them easily and reliably in your environment.
We get it. So we built Lightbend Enterprise Suite to help you do that, and more, with a range of powerful Application Management, Intelligent Monitoring, Enterprise Integration and Advanced Tooling features.