SlideShare a Scribd company logo
What Constitutes a Reactive Application 
Reactive Patterns Applied 
Henrik Engstrom 
Software Engineer 
@h3nk3
2
3 
Activator UI! 
(JavaScript, Knockout, CSS3, black magic…) 
websockets 
Play Application! 
(Play 2.3.x, Akka 2.3.x, sbt 0.13.x) 
sbt protocol 
sbt Server 
Async Communication! 
Websockets! 
Akka Actors 
Other 
Clients 
(Eclipse, 
Terminal, etc.)
DEMO 
4
The Four Reactive Traits 
Reactive Applications 
5 
http://reactivemanifesto.org/
Message-Driven 
! 
The Foundation of being Reactive
Akka Actors in 5 minutes or so… 
7
8 
ACTORS
import akka.actor._ 
! 
class GreetingActor extends Actor with ActorLogging { 
9 
import GreetingActor._ 
def receive = { 
case User(name) => 
log.info(s“Hello there ${name}”) 
} 
} 
! 
object GreetingActor { 
case class User(name: String) 
def props: Props = Props(classOf[GreetingActor]) 
}
10 
MAILBOXES
11 
THREADS
12 
STATE
13 
CONTAINERS
14 
val system = ActorSystem(“MySystem”) 
val greeter: ActorRef = 
system.actorOf(GreetingActor.props, “greeter”)
15 
MESSAGES
16 
greeter ! GreetingActor.User(“PlayNYC”) 
// or 
greeter.tell(GreetingActor.User(“PlayNYC”))
17 
import akka.actor._ 
! 
object Sample extends App { 
val system = ActorSystem(“MySystem”) 
val greeter = system.actorOf(GreetingActor.props, “greeter”) 
greeter ! GreetingActor.User(“PlayNYC”) 
Thread.sleep(1000) // wait a little before shutting down 
system.shutdown() 
} 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
case GreetingActor.User(name) => 
log.info(s“Hello there ${name}”) 
} 
} 
! 
object GreetingActor { 
case class User(name: String) 
def props: Props = Props(classOf[GreetingActor]) 
}
18 
he-mbp:sample he$ scalac Sample.scala 
! 
he-mbp:sample he$ scala Sample 
! 
[INFO] [09/15/2014 16:57:19.879] [MySystem-akka.actor.default-dispatcher- 
4] [akka://MySystem/user/greeter] Hello there PlayNYC 
! 
he-mbp:sample he$
Resilient 
! 
Responsive in the Face of Failure
20 
SUPERVISION
21 
import akka.actor.OneForOneStrategy 
import akka.actor.SupervisorStrategy._ 
import scala.concurrent.duration._ 
class SupervisorActor extends Actor with ActorLogging { 
override val supervisorStrategy = 
OneForOneStrategy(maxNrOfRetries = 10, 
withinTimeRange = 1 minute) { 
case _: SomeDbException => Resume 
case _: SomeOtherDbException => Restart 
case _: Exception => Escalate 
} 
! 
val dbActor = context.actorOf(DbActor.props) 
def receive = { 
case op: SomeDbOperation => 
dbActor forward op 
} 
}
22 
BULKHEAD
23 
CIRCUIT 
BREAKER
Elastic 
! 
Responsive in the Face of Changing Load
25 
SOME CHALLENGES 
• Each user has state Proxy 
(location) 
• Horizontal scaling => !sticky sessions 
• How do we route to the right node? 
• Node Crashes 
Proxy Play is App SPOF 
1 Play App2 Play App n 
• …
26 
Play App 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node
27 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Shard 
Coord. 
Shard 
Region 
Shard 
Region 
Shard 
Region 
Shard 
Region
Supported HTTP commands (Play routes file) 
! 
GET / controller.Application.index 
PUT /create/user/:userId c.Application.createUser(userId: String) 
POST /update/user/:userId c.Application.updateUser(userId: String) 
28
29 
package controller 
object Application extends Controller { 
val userController = 
AppGlobal.system.actorOf(UserController.props) 
! 
def index = Action { 
Ok(“Node is up”) 
} 
! 
def createUser(userId: String) = Action { 
userController ! UserController.CreateUser(userId) 
Ok("new user is created") 
} 
! 
def updateUser(userId: String) = Action { 
userController ! UserController.UpdateUser(userId, 
request.getQueryString(“msg")) 
Ok("user is updated") 
} 
}
30 
object AppGlobal extends GlobalSettings { 
private[this] var _system: Option[ActorSystem] = None 
def system = _system.getOrElse(throw new RuntimeException(“…”)) 
! 
override def onStart(app: Application) = { 
_system = Some(ActorSystem(“ClusterSystem”)) 
_system.foreach(createShard(_)) 
} 
! 
override def onStop(app: Application) = { 
system.foreach(_.shutdown()) 
} 
! 
private def createShard(system: ActorSystem) = { 
ClusterSharding(system).start( 
typeName = User.shardName, 
entryProps = Some(User.props), 
idExtractor = User.idExtractor, 
shardResolver = User.shardResolver 
) 
} 
}
31 
object User { 
val shardName = "users" 
def props: Props = Props(classOf[User]) 
! 
trait UserMessage { def userId: String } 
case class CreateUser(userId: String) 
extends UserMessage 
case class UpdateUser(userId: String, text: String) 
extends UserMessage 
val idExtractor: ShardRegion.IdExctrator = { 
case um: UserMessage => (um.userId, um) 
} 
val shardResolver: ShardRegion.ShardResolver = { 
case um: UserMessage => 
(Math.abs(um.userId.hashCode) % 20).toString 
} 
}
32 
class User extends Actor with ActorLogging { 
var currentMessage: Option[String] = None 
def receive = { 
case CreateUser(userId) => 
currentMessage = Some(s"User created: ${userId}”) 
case UpdateUser(userId, text) => 
log.info(s“User ${userId} now has msg ${text}”) 
currentMessage = Some(text) 
} 
}
33 
akka { 
actor.provider = "akka.cluster.ClusterActorRefProvider" 
remote.nettytcp { 
port = 0 
hostname = "127.0.0.1" 
} 
! 
remote.log-remote-lifecycle-events = on 
! 
cluster { 
seed-nodes = [ 
"akka.tcp://ClusterSystem@127.0.0.1:2551", 
"akka.tcp://ClusterSystem@127.0.0.1:2552" 
] 
} 
! 
auto-down-unreachable-after = 30s 
}
34 
Play App 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node 
Akka! 
Cluster! 
Node
Responsive 
! 
Always Available - 
Interactive - 
(near) Real-Time
36 
package controllers 
! 
import play.api._ 
import play.api.mvc._ 
import play.api.libs.json._ 
import play.api.Play.current 
import actors.WebSocketActor 
! 
object Application extends Controller { 
def index = Action { 
Ok(views.html.index("Your new application is ready.")) 
} 
! 
def socket = WebSocket.acceptWithActor[JsValue, JsValue] { 
request => out => 
WebSocketActor.props(out) 
} 
}
37 
object WebSocketActor { 
def props(out: ActorRef) = Props(new WebSocketActor(out)) 
case object Again 
} 
! 
class WebSocketActor(out: ActorRef) extends Actor { 
import WebSocketActor._ 
var user: Option[String] = None 
def receive = { 
case json: JsValue => 
val name = (json  "name").as[String] 
user = Some(name) 
reply(name) 
context.system.scheduler.scheduleOnce(3 seconds, self, Again) 
case Again => 
user.foreach{reply(_)} 
} 
! 
def reply(name: String) = { 
out ! Json.obj("message" -> s"Hello there ${name}") 
} 
}
# routes file 
GET / controllers.Application.index 
GET /socket controllers.Application.socket 
! 
> var ws = new WebSocket("ws://localhost:9000/socket"); 
> ws.onmessage = function(msg) { console.log(">", msg); }; 
> ws.send(JSON.stringify({"name": “PlayNYC"})); 
! 
> MessageEvent {ports: Array[0], data: "{"message":"Hello 
there PlayNYC"}", source: null, lastEventId: "", origin: 
"ws://localhost:9000"…} 
! 
> MessageEvent {ports: Array[0], data: "{"message":"Hello 
there PlayNYC"}", source: null, lastEventId: "", origin: 
"ws://localhost:9000"…} 
38
import play.api.libs.json._ 
import play.api.mvc.WebSocket.FrameFormatter 
! 
implicit val inEventFormat = Json.format[InEvent] 
implicit val outEventFormat = Json.format[OutEvent] 
! 
//Play provides default FrameFormatter for String or JsValue 
implicit val inEFF = FrameFormatter.jsonFrame[InEvent] 
implicit val outEFF = FrameFormatter.jsonFrame[OutEvent] 
! 
def socket = WebSocket.acceptWithActor[InEvent, OutEvent] { 
request => out => 
WebSocketActor.props(out) 
} 
39
40 
Request Response 
Coord 
Actor 
Entry 
Actor 
TwActor FBActor WActor 
Twitter Facebook weather.com
RESOURCES 
! 
Activator - get it now! 
http://typesafe.com/platform/getstarted 
! 
Awesome Example Code by Nilanjan Raychaudhuri 
https://github.com/nraychaudhuri/scaladays2014/tree/master/ 
play-akka-sharding 
! 
Play Websockets 
https://www.playframework.com/documentation/2.3.x/ 
ScalaWebSockets 
! 
Akka Cluster Sharding 
http://doc.akka.io/docs/akka/2.3.6/contrib/cluster-sharding. 
41 
html
The Four Reactive Traits 
Reactive Applications 
42 
http://reactivemanifesto.org/
©Typesafe 2014 – All Rights Reserved 
All images in this presentation are from www.morguefile.com

More Related Content

PDF
Class-based views with Django
PDF
Scala ActiveRecord
PDF
Akka and the Zen of Reactive System Design
PDF
Codegeneration With Xtend
PPTX
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
PDF
Akka Cluster in Java - JCConf 2015
PPTX
Art of Javascript
PDF
Why Task Queues - ComoRichWeb
Class-based views with Django
Scala ActiveRecord
Akka and the Zen of Reactive System Design
Codegeneration With Xtend
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Akka Cluster in Java - JCConf 2015
Art of Javascript
Why Task Queues - ComoRichWeb

What's hot (20)

PDF
Scala active record
ZIP
Barcamp Auckland Rails3 presentation
PDF
Building DSLs With Eclipse
PDF
Http4s, Doobie and Circe: The Functional Web Stack
PPTX
Workshop 1: Good practices in JavaScript
PDF
Why Every Tester Should Learn Ruby
PPTX
Owl: The New Odoo UI Framework
PDF
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
PDF
Celery - A Distributed Task Queue
PDF
Django Celery - A distributed task queue
PPT
55 New Features in Java 7
PPTX
Javascript And J Query
PDF
Rails on Oracle 2011
PDF
Sane Sharding with Akka Cluster
PDF
Akka Futures and Akka Remoting
PDF
How to write easy-to-test JavaScript
PDF
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
PPTX
Code generation for alternative languages
DOC
Ad java prac sol set
PPTX
Javascript Testing with Jasmine 101
Scala active record
Barcamp Auckland Rails3 presentation
Building DSLs With Eclipse
Http4s, Doobie and Circe: The Functional Web Stack
Workshop 1: Good practices in JavaScript
Why Every Tester Should Learn Ruby
Owl: The New Odoo UI Framework
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Celery - A Distributed Task Queue
Django Celery - A distributed task queue
55 New Features in Java 7
Javascript And J Query
Rails on Oracle 2011
Sane Sharding with Akka Cluster
Akka Futures and Akka Remoting
How to write easy-to-test JavaScript
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Code generation for alternative languages
Ad java prac sol set
Javascript Testing with Jasmine 101
Ad

Viewers also liked (20)

PPTX
Moral dilema power point
PDF
Mitra pinasthika mulia development area supervisor
PDF
Sleep Patterns
PPTX
Presentation
PDF
8911366 loto-praxias-labioseugenia-romero[1]
PDF
Membersihkan jerawat menggunakan healing brush tool
PPTX
Social media: Is it for me?
PPT
Script en msdos
PDF
2016 02-25-crawler-study-01
DOC
Modul manajemen pemasaran
PPTX
Marketing plan ppt slides
PPTX
Blue ocean strategy ppt slides
PDF
10 step sales process
PDF
Real estate trends in 2016
PDF
Real Estate Marketing Through Story Telling 101 | Matthew Rathbun
PDF
The Top 10 Sales Conferences of 2016
PDF
The 5 steps to Sales Dominance
PDF
VC survey data 2016
PDF
Upfront vc analysis 2016
PDF
The Minimum Loveable Product
Moral dilema power point
Mitra pinasthika mulia development area supervisor
Sleep Patterns
Presentation
8911366 loto-praxias-labioseugenia-romero[1]
Membersihkan jerawat menggunakan healing brush tool
Social media: Is it for me?
Script en msdos
2016 02-25-crawler-study-01
Modul manajemen pemasaran
Marketing plan ppt slides
Blue ocean strategy ppt slides
10 step sales process
Real estate trends in 2016
Real Estate Marketing Through Story Telling 101 | Matthew Rathbun
The Top 10 Sales Conferences of 2016
The 5 steps to Sales Dominance
VC survey data 2016
Upfront vc analysis 2016
The Minimum Loveable Product
Ad

Similar to Activator and Reactive at Play NYC meetup (20)

PDF
Message-based communication patterns in distributed Akka applications
PDF
Scalaz 8 vs Akka Actors
PPTX
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
PDF
Akka with Scala
KEY
JavaScript Growing Up
PDF
Asynchronous web apps with the Play Framework 2.0
KEY
Akka london scala_user_group
PPTX
Intro to Reactive Thinking and RxJava 2
PDF
Reactive Programming in .Net - actorbased computing with Akka.Net
PDF
Clojure - A new Lisp
PDF
Ajax tutorial
PDF
RxJS101 - What you need to know to get started with RxJS tomorrow
PDF
From polling to real time: Scala, Akka, and Websockets from scratch
PPT
jQuery for beginners
PPTX
Tools for Making Machine Learning more Reactive
PPTX
Async Redux Actions With RxJS - React Rally 2016
PPTX
JavaScript (without DOM)
PPTX
Rx workshop
PDF
Play vs Rails
PDF
Akka lsug skills matter
Message-based communication patterns in distributed Akka applications
Scalaz 8 vs Akka Actors
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
Akka with Scala
JavaScript Growing Up
Asynchronous web apps with the Play Framework 2.0
Akka london scala_user_group
Intro to Reactive Thinking and RxJava 2
Reactive Programming in .Net - actorbased computing with Akka.Net
Clojure - A new Lisp
Ajax tutorial
RxJS101 - What you need to know to get started with RxJS tomorrow
From polling to real time: Scala, Akka, and Websockets from scratch
jQuery for beginners
Tools for Making Machine Learning more Reactive
Async Redux Actions With RxJS - React Rally 2016
JavaScript (without DOM)
Rx workshop
Play vs Rails
Akka lsug skills matter

Recently uploaded (20)

PPTX
Online Work Permit System for Fast Permit Processing
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
ai tools demonstartion for schools and inter college
PDF
Nekopoi APK 2025 free lastest update
PPT
Introduction Database Management System for Course Database
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
System and Network Administraation Chapter 3
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
top salesforce developer skills in 2025.pdf
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Online Work Permit System for Fast Permit Processing
Softaken Excel to vCard Converter Software.pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
ai tools demonstartion for schools and inter college
Nekopoi APK 2025 free lastest update
Introduction Database Management System for Course Database
How to Migrate SBCGlobal Email to Yahoo Easily
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Design an Analysis of Algorithms II-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Design an Analysis of Algorithms I-SECS-1021-03
PTS Company Brochure 2025 (1).pdf.......
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
System and Network Administraation Chapter 3
How Creative Agencies Leverage Project Management Software.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
top salesforce developer skills in 2025.pdf
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)

Activator and Reactive at Play NYC meetup

  • 1. What Constitutes a Reactive Application Reactive Patterns Applied Henrik Engstrom Software Engineer @h3nk3
  • 2. 2
  • 3. 3 Activator UI! (JavaScript, Knockout, CSS3, black magic…) websockets Play Application! (Play 2.3.x, Akka 2.3.x, sbt 0.13.x) sbt protocol sbt Server Async Communication! Websockets! Akka Actors Other Clients (Eclipse, Terminal, etc.)
  • 5. The Four Reactive Traits Reactive Applications 5 http://reactivemanifesto.org/
  • 6. Message-Driven ! The Foundation of being Reactive
  • 7. Akka Actors in 5 minutes or so… 7
  • 9. import akka.actor._ ! class GreetingActor extends Actor with ActorLogging { 9 import GreetingActor._ def receive = { case User(name) => log.info(s“Hello there ${name}”) } } ! object GreetingActor { case class User(name: String) def props: Props = Props(classOf[GreetingActor]) }
  • 14. 14 val system = ActorSystem(“MySystem”) val greeter: ActorRef = system.actorOf(GreetingActor.props, “greeter”)
  • 16. 16 greeter ! GreetingActor.User(“PlayNYC”) // or greeter.tell(GreetingActor.User(“PlayNYC”))
  • 17. 17 import akka.actor._ ! object Sample extends App { val system = ActorSystem(“MySystem”) val greeter = system.actorOf(GreetingActor.props, “greeter”) greeter ! GreetingActor.User(“PlayNYC”) Thread.sleep(1000) // wait a little before shutting down system.shutdown() } ! class GreetingActor extends Actor with ActorLogging { def receive = { case GreetingActor.User(name) => log.info(s“Hello there ${name}”) } } ! object GreetingActor { case class User(name: String) def props: Props = Props(classOf[GreetingActor]) }
  • 18. 18 he-mbp:sample he$ scalac Sample.scala ! he-mbp:sample he$ scala Sample ! [INFO] [09/15/2014 16:57:19.879] [MySystem-akka.actor.default-dispatcher- 4] [akka://MySystem/user/greeter] Hello there PlayNYC ! he-mbp:sample he$
  • 19. Resilient ! Responsive in the Face of Failure
  • 21. 21 import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ class SupervisorActor extends Actor with ActorLogging { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: SomeDbException => Resume case _: SomeOtherDbException => Restart case _: Exception => Escalate } ! val dbActor = context.actorOf(DbActor.props) def receive = { case op: SomeDbOperation => dbActor forward op } }
  • 24. Elastic ! Responsive in the Face of Changing Load
  • 25. 25 SOME CHALLENGES • Each user has state Proxy (location) • Horizontal scaling => !sticky sessions • How do we route to the right node? • Node Crashes Proxy Play is App SPOF 1 Play App2 Play App n • …
  • 26. 26 Play App Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node
  • 27. 27 Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node Shard Coord. Shard Region Shard Region Shard Region Shard Region
  • 28. Supported HTTP commands (Play routes file) ! GET / controller.Application.index PUT /create/user/:userId c.Application.createUser(userId: String) POST /update/user/:userId c.Application.updateUser(userId: String) 28
  • 29. 29 package controller object Application extends Controller { val userController = AppGlobal.system.actorOf(UserController.props) ! def index = Action { Ok(“Node is up”) } ! def createUser(userId: String) = Action { userController ! UserController.CreateUser(userId) Ok("new user is created") } ! def updateUser(userId: String) = Action { userController ! UserController.UpdateUser(userId, request.getQueryString(“msg")) Ok("user is updated") } }
  • 30. 30 object AppGlobal extends GlobalSettings { private[this] var _system: Option[ActorSystem] = None def system = _system.getOrElse(throw new RuntimeException(“…”)) ! override def onStart(app: Application) = { _system = Some(ActorSystem(“ClusterSystem”)) _system.foreach(createShard(_)) } ! override def onStop(app: Application) = { system.foreach(_.shutdown()) } ! private def createShard(system: ActorSystem) = { ClusterSharding(system).start( typeName = User.shardName, entryProps = Some(User.props), idExtractor = User.idExtractor, shardResolver = User.shardResolver ) } }
  • 31. 31 object User { val shardName = "users" def props: Props = Props(classOf[User]) ! trait UserMessage { def userId: String } case class CreateUser(userId: String) extends UserMessage case class UpdateUser(userId: String, text: String) extends UserMessage val idExtractor: ShardRegion.IdExctrator = { case um: UserMessage => (um.userId, um) } val shardResolver: ShardRegion.ShardResolver = { case um: UserMessage => (Math.abs(um.userId.hashCode) % 20).toString } }
  • 32. 32 class User extends Actor with ActorLogging { var currentMessage: Option[String] = None def receive = { case CreateUser(userId) => currentMessage = Some(s"User created: ${userId}”) case UpdateUser(userId, text) => log.info(s“User ${userId} now has msg ${text}”) currentMessage = Some(text) } }
  • 33. 33 akka { actor.provider = "akka.cluster.ClusterActorRefProvider" remote.nettytcp { port = 0 hostname = "127.0.0.1" } ! remote.log-remote-lifecycle-events = on ! cluster { seed-nodes = [ "akka.tcp://ClusterSystem@127.0.0.1:2551", "akka.tcp://ClusterSystem@127.0.0.1:2552" ] } ! auto-down-unreachable-after = 30s }
  • 34. 34 Play App Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node Akka! Cluster! Node
  • 35. Responsive ! Always Available - Interactive - (near) Real-Time
  • 36. 36 package controllers ! import play.api._ import play.api.mvc._ import play.api.libs.json._ import play.api.Play.current import actors.WebSocketActor ! object Application extends Controller { def index = Action { Ok(views.html.index("Your new application is ready.")) } ! def socket = WebSocket.acceptWithActor[JsValue, JsValue] { request => out => WebSocketActor.props(out) } }
  • 37. 37 object WebSocketActor { def props(out: ActorRef) = Props(new WebSocketActor(out)) case object Again } ! class WebSocketActor(out: ActorRef) extends Actor { import WebSocketActor._ var user: Option[String] = None def receive = { case json: JsValue => val name = (json "name").as[String] user = Some(name) reply(name) context.system.scheduler.scheduleOnce(3 seconds, self, Again) case Again => user.foreach{reply(_)} } ! def reply(name: String) = { out ! Json.obj("message" -> s"Hello there ${name}") } }
  • 38. # routes file GET / controllers.Application.index GET /socket controllers.Application.socket ! > var ws = new WebSocket("ws://localhost:9000/socket"); > ws.onmessage = function(msg) { console.log(">", msg); }; > ws.send(JSON.stringify({"name": “PlayNYC"})); ! > MessageEvent {ports: Array[0], data: "{"message":"Hello there PlayNYC"}", source: null, lastEventId: "", origin: "ws://localhost:9000"…} ! > MessageEvent {ports: Array[0], data: "{"message":"Hello there PlayNYC"}", source: null, lastEventId: "", origin: "ws://localhost:9000"…} 38
  • 39. import play.api.libs.json._ import play.api.mvc.WebSocket.FrameFormatter ! implicit val inEventFormat = Json.format[InEvent] implicit val outEventFormat = Json.format[OutEvent] ! //Play provides default FrameFormatter for String or JsValue implicit val inEFF = FrameFormatter.jsonFrame[InEvent] implicit val outEFF = FrameFormatter.jsonFrame[OutEvent] ! def socket = WebSocket.acceptWithActor[InEvent, OutEvent] { request => out => WebSocketActor.props(out) } 39
  • 40. 40 Request Response Coord Actor Entry Actor TwActor FBActor WActor Twitter Facebook weather.com
  • 41. RESOURCES ! Activator - get it now! http://typesafe.com/platform/getstarted ! Awesome Example Code by Nilanjan Raychaudhuri https://github.com/nraychaudhuri/scaladays2014/tree/master/ play-akka-sharding ! Play Websockets https://www.playframework.com/documentation/2.3.x/ ScalaWebSockets ! Akka Cluster Sharding http://doc.akka.io/docs/akka/2.3.6/contrib/cluster-sharding. 41 html
  • 42. The Four Reactive Traits Reactive Applications 42 http://reactivemanifesto.org/
  • 43. ©Typesafe 2014 – All Rights Reserved All images in this presentation are from www.morguefile.com