Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング

Sept 06 2014
Ngoc Dao 
https://github.com/ngocdaothanh 
Takeharu Oshida 
https://github.com/georgeOsdDev 
http://mobilus.co.jp/
What is 
Xitrum? 
Xitrum is an async and clustered ! 
Scala web framework and HTTP(S) server ! 
on top of Netty, Akka
Why you should use 
Xitrum? 
• Featureful! 
• Easy to use! 
• High performance 
Scala, Netty, and Akka are fast! 
• Scalable 
Can scale to a cluster of servers using 
Akka cluster and/or Hazelcast
Homepage: 
http://xitrum-framework.github.io/ 
(there are various demos) 
Guides (English, Japanese, Russian): 
http://xitrum-framework.github.io/guide.html 
(Korean version is in progress) 
! 
Community (Google Group): 
https://groups.google.com/forum/#!forum/ 
xitrum-framework
Where 
Xitrum is used? 
KONNECT (Messaging Service)! 
http://mobilus.co.jp/konnect/! 
! 
KONNECT can be used in mobile games, 
mobiles apps, SNS websites etc. 
Xitrum is also being used in France, Korea, 
Russia, Singapore etc.
Xitrum:! 
WebSocket (SockJS)! 
CORS support
2010-2013 Xitrum 1.x-2.x 
http://bit.ly/xitrum13 
2014 Xitrum 3.x 
• Netty 4.x 
• Swagger 
• Component 
• FileMonitor, i18n 
• CORS 
• WebJARs 
• Glokka 
• Agent7 (autoreload classes on change) 
! 
! 
http://bit.ly/xitrum-changelog 
!
How Xitrum 
works?
Client 
Netty 
Async 
Dispatch 
request 
Action FutureAction ActorAction 
Akka 
Xitrum 
I/O thread pool to 
accept requests and reply 
responses 
Thread pool 
to run FutureAction and 
ActorAction 
Client 
Run directly on 
Netty I/O thread 
Netty handler 
Netty handler 
Netty handler 
Netty handler 
Xitrum 
Your program
http://bit.ly/xitrum-handlers
Client 
Client Client 
Akka cluster (code)! 
Hazelcast (data) 
Client 
Netty 
Xitrum 
A FA AA 
Akka 
Netty 
Xitrum 
A FA AA 
Akka 
Server N Server N+1
Embed Xitrum 
object MyApp { 
def main(args: Array[String]) { 
... 
// Somewhere in your app 
xitrum.Server.start() 
... 
} 
1. Collect routes! 
} 
! 
2. Start HTTP/HTTPS servers
Action example 
import xitrum.Action 
import xitrum.annotation.GET 
! 
@GET("hello") 
class MyAction extends Action { 
def execute() { 
respondText("Hello") 
} 
} 
FutureAction! 
ActorAction
Annotations: Scala vs Java 
Scala: @GET("matsuri", "festival") 
Java: @GET(Array("matsuri", "festival")) 
! 
Scala: 
case class GET(paths: String*) extends 
scala.annotation.StaticAnnotation 
! 
Java: 
public @interface GET { 
String[] value(); 
}
Benefits of using annotations 
Routes in .class and .jar in classpath are 
automatically collected and merged. 
A.class 
B.class 
lib1.jar 
lib2.jar 
Routes
Problem with annotations 
Collecting routes from .class and .jar files is slow.! 
! 
Solutions:! 
• In development mode, routes in .class and .jar 
files that are not in the current working directory 
are cached to file routes.cache. 
• To avoid loading lots of classes, don't collect 
routes from: java.xxx, javax.xxx, scala.xxx, 
sun.xxx, com.sun.xxx
Annotations defined by Xitrum:! 
http://bit.ly/xitrum-annotations! 
! 
Lib to scan classes in classpath to collect routes:! 
https://github.com/xitrum-framework/sclasner
Demo overview 
GET / GET /chat 
username 
password 
login 
Hello 
! 
Hello! 
How are you? 
Fine 
message send 
POST /login SockJS /connect 
https://github.com/xitrum-framework/matsuri14
Demo overview 
• Simple HTTP CRUD with MongoDB 
POST /admin/user 
GET /admin/user 
GET /admin/user/:userId 
PUT /admin/user/:userId 
DELETE /admin/user/:userId 
PUT/PATCH/DELETE can be emulated via 
POST with _method=PUT/PATCH/DELETE 
! 
• API documentation with Swagger
DB Cluseter 
Xitrum1 Akka Hazelcast 
Xitrum2 Akka Hazelcast 
Xitrum3 
Cluster 
LB 
(HAProxy, Nginx, 
Route53 etc.) 
NoSQL 
RDB 
Other services 
Akka Hazelcast 
https://github.com/xitrum-framework/glokka 
https://github.com/xitrum-framework/xitrum-hazelcast
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Getting started 
with xitrum-new 
skeleton 
https://github.com/xitrum-framework/xitrum-new 
https://github.com/xitrum-framework/xitrum-scalate
@GET("admin") 
class AdminIndex extends Action { 
def execute() { 
// Get all users 
val users = User.listAll() 
// Pass users to view template 
at("users") = users 
! 
// Response respons view with template 
respondView() 
} 
} 
ActorAction 
FutureAction 
Action
- import matsuri.demo.action._! 
- import matsuri.demo.model.User! 
! 
div.row#usersTable! 
table.table.table-striped#messageTable! 
thead! 
tr.bg-primary! 
View 
• Scalate template with jade 
(mustache, scaml, or ssp) 
• "at" function 
• i18n with GNU gettext 
th.col-xs-2 =t("Name")! 
th.col-xs-2 =t("Age")! 
th.col-xs-2 =t("Desc")! 
th.col-xs-2 =t("Created time")! 
th.col-xs-2 =t("Updated time")! 
th.col-xs-2 =t("Last login time")! 
tbody! 
- for (user <- at("users").asInstanceOf[List[User]])! 
tr! 
th! 
a(href={url[AdminUserShow](("name", user.name))}) = user.name! 
th = user.age! 
th = user.desc! 
th = user.createdAtAsStr! 
th = user.updatedAtAsStr! 
th = user.lastLoginAsStr
└── src 
└── scalate 
└── matsuri 
└── demo 
└── action 
├── AdminIndex.jade 
└── DefaultLayout.jade 
package matsuri.demo.action 
! 
import xitrum.Action 
! 
trait DefaultLayout extends Action { 
override def layout = 
renderViewNoLayout[DefaultLayout]() 
} 
Layout
!!! 5 
html 
head 
!= antiCsrfMeta 
!= xitrumCss 
! 
meta(content="text/html; charset=utf-8" http-equiv="content-type") 
title ScalaMatsuri2014 Xitrum Demo 
! 
link(rel="shortcut icon" href={publicUrl("favicon.ico")}) 
link(type="text/css" rel="stylesheet" media="all" href={webJarsUrl("bootstrap/3.2.0/css", 
"bootstrap.css", "bootstrap.min.css")}) 
link(type="text/css" rel="stylesheet" media="all" href={publicUrl("app.css")}) 
! 
body 
.container 
h1 
! 
#flash 
!~ jsRenderFlash() 
!= renderedView 
Layout 
! 
!= jsDefaults 
script(src={webJarsUrl("bootstrap/3.2.0/js", "bootstrap.js", "bootstrap.min.js")}) 
script(src={webJarsUrl("underscorejs/1.6.0", "underscore.js", "underscore-min.js")}) 
!= jsForView
form(role="form" method="post" action={url[AdminUserCreate]}) 
!= antiCsrfInput 
div.modal-header 
button.close(type="button" data-dismiss="modal") 
Form 
span(aria-hidden="true") &times; 
span.sr-only =t("Close") 
h4.modal-title#myModalLabel =t("Create New User") 
div.modal-body 
div.form-group 
label(for="newUserName") =t("Name") 
input.form-control#newUserName(name="name" type="text" 
• "url" function 
• jquery-validation 
• Anti csrf token 
placeholder={t("Enter Name")} minlength=5 maxlenght=10 required=true) 
div.form-group 
label(for="newUserPass") =t("Password") 
input.form-control#newUserPass(name="password" type="password" 
placeholder={t("Enter Password")} minlength=8 required=true) 
! 
div.modal-footer 
button.btn.btn-default(type="button" data-dismiss="modal") = t("Cancel") 
button.btn.btn-primary(type="submit") = t("Save")
@POST("admin/user") 
class AdminUserCreate extends AdminAction { 
def execute() { 
// Get request paramaters 
val name = param("name") 
val password = param("password") 
// Optional parameters 
val age = paramo[Int]("age") 
val desc = paramo("desc") 
! 
Required.exception("name", name) 
Required.exception("password", password) 
! 
User.create(name, password, age, desc) 
flash(t("Success")) 
redirectTo[AdminIndex]() 
} 
Get 
request 
params 
with 
param(s) 
and 
param(o)
object SVar { 
object isAdmin extends SessionVar[Boolean] 
} 
Use before filter 
to check 
trait AdminFilter { 
this: Action => 
! 
beforeFilter { 
if (SVar.isAdmin.isDefined) true else authBasic() 
} 
! 
private def authBasic(): Boolean = { 
basicAuth(Config.basicAuth.realm) { (username, password) => 
if (username == Config.basicAuth.name && password == Config.basicAuth.pass) { 
SVar.isAdmin.set(true) 
true 
} else { 
false 
} 
} 
} 
authentication 
info in session
@Swagger( 
Swagger.Summary("Create User"), 
Swagger.Response(200, "status = 0: success, 1: failed to create user"), 
Swagger.Response(400, "Invalid request parameter"), 
Swagger.StringForm("name"), 
Swagger.StringForm("password"), 
Swagger.OptIntForm("age"), 
Swagger.OptStringForm("desc") 
) 
API 
doc 
• /xitrum/swagger 
• /xitrum/swagger-ui 
• Create test client with Swagger-codegen 
https://github.com/wordnik/swagger-ui 
https://github.com/wordnik/swagger-codegen 
https://github.com/wordnik/swagger-spec
@GET("login", "") 
class LoginIndex extends DefaultLayout { 
def execute() { 
respondView() 
} 
} 
! 
@POST("login") 
class Login extends Action { 
def execute() { 
session.clear() 
val name = param("name") 
val password = param("password") 
! 
User.authLogin(name, password) match { 
case Some(user) => 
SVar.userName.set(user.name) 
redirectTo[ChatIndex]() 
! 
case None => 
flash(t(s"Invalid username or password")) 
redirectTo[LoginIndex]() 
} 
} 
} 
Login
jsAddToView( 
"var url = '" + sockJsUrl[ChatAction] + "';" + 
""" 
var socket; 
var initSocket = function() { 
socket = new SockJS(url); 
socket.onopen = function(event) { 
console.log("socket onopen", event.data); 
socket.send(JSON.parse({"msg":"Hello Xitrum"})); 
}; 
socket.onclose = function(event) {console.log("socket onclose", event.data);}; 
socket.onmessage = function(event) {console.log("socket onmessage", event.data);}; 
}; 
initSocket(); 
""" 
) 
!= jsDefaults 
script(src={webJarsUrl("bootstrap/3.2.0/js", "bootstrap.js", "bootstrap.min.js")}) 
script(src={webJarsUrl("underscorejs/1.6.0", "underscore.js", "underscore-min.js")}) 
!= jsForView 
• jsAddToView/jsForView 
• sockJsUrl 
• webJarsUrl 
Create 
chat 
client 
with 
SockJS
import xitrum.{SockJsAction, SockJsText} 
import xitrum.annotation.SOCKJS 
! 
@SOCKJS("connect") 
class ChatAction extends SockJsAction with LoginFilter { 
def execute() { 
context.become { 
SockJsAction 
(an Actor) 
case SockJsText(text) => 
SeriDeseri.fromJson[Map[String, String]](text) match { 
case Some(jsonMap) => 
// echo 
respondSockJsText(SeriDeseri.toJson(jsonMap)) 
case None => 
log.warn(s"Failed to parse request: $text") 
respondSockJsText("invalid request") 
} 
Create 
} 
• SockJsAction 
• SockJsText/respondSockJsText 
• SeriDeseri.fromJson[T] / SeriDeseri.toJson(ref:AnyRef)
Lookup 
singleton 
Actor 
with 
Glokka 
Xitrum 
socket open 
Client 
HubActor 
trait Hub extends Actor { 
protected var clients = Seq[ActorRef]() 
def receive = { 
case Subscribe(option) => 
clients = clients :+ sender 
case Unsubscribe(option) => 
clients = clients.filterNot(_ == sender) 
case Terminated(client) => 
clients = clients.filterNot(_ == client) 
case ignore => 
} 
import glokka.Registry 
object Hub { 
val KEY_PROXY = "HUB_PROXY" 
val actorRegistry = Registry.start(Config.actorSystem, 
KEY_PROXY) 
} 
! 
def lookUpHub(key: String, hubProps: Props, option: Any = None) 
{ 
Hub.actorRegistry ! Registry.Register(key, hubProps) 
context.become { 
hub ! Subscribe 
ChatAction ChatAction ChatAction ChatAction 
case result: Registry.FoundOrCreated => 
result.ref ! Subscribe 
} 
} 
Client Client Client 
https://github.com/xitrum-framework/glokka
Messaging overview 
SockJsText! 
(socket.send) hub ! Push(msg) 
clients.foreach { _ ! Publish(msg)} respondSockJSText(msg:String) 
Client ChatAction HubActor 
socket.onmessage 
SockJsText hub ! Pull(msg) 
case class Done (option: Map[String, Any] = Map.empty) // Hub -> Action 
case class Publish(option: Map[String, Any] = Map.empty) // Hub -> Action 
case class Pull (option: Map[String, Any] = Map.empty) // Action -> Hub 
case class Push (option: Map[String, Any] = Map.empty) // Action -> Hub 
https://github.com/georgeOsdDev/glokka-demo 
ChatAction Client 
ChatAction 
ChatAction 
Client 
Client 
respondSockJSText(msg:String) sender ! Done(msg) 
Client ChatAction HubActor 
respondSockJSText(msg:String) sender ! Done(msg) 
socket.onmessage
Cluster config for Hazelcast 
hazelcastMode = clusterMember 
! 
cache = xitrum.hazelcast.Cache 
#cache { 
# # Simple in-memory cache 
# "xitrum.local.LruCache" { 
xitrum.conf 
# maxElems = 10000 
# } 
• Xitrum-hazelcast 
#} 
• Shared Session 
• Shared Cache 
! 
session { 
store = xitrum.hazelcast.Session 
# Store sessions on client side 
#store = xitrum.scope.session.CookieSessionStore
akka { 
loggers = ["akka.event.slf4j.Slf4jLogger"] 
logger-startup-timeout = 30s 
! 
actor { 
provider = "akka.cluster.ClusterActorRefProvider" 
} 
! 
# This node 
remote { 
log-remote-lifecycle-events = off 
netty.tcp { 
hostname = "127.0.0.1" 
port = 2551 # 0 means random port 
} 
} 
! 
cluster { 
seed-nodes = [ 
"akka.tcp://xitrum@127.0.0.1:2551", 
"akka.tcp://xitrum@127.0.0.1:2552"] 
! 
auto-down-unreachable-after = 10s 
} 
} 
Cluster 
config 
for 
Akka
Live class reload 
during development 
https://github.com/xitrum-framework/agent7 
https://github.com/dcevm/dcevm 
java -javaagent:`dirname $0`/agent7-1.0.jar 
-XXaltjvm=dcevm -Xms256M -Xmx512M -Xss1M 
-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M 
-jar `dirname $0`/sbt-launch-0.13.5.jar "$@" 
https://github.com/xitrum-framework/xitrum-package
Package project for 
deploying to 
production server 
https://github.com/xitrum-framework/xitrum-package 
sbt/sbt xitrum-package
Monitor Xitrum 
in production mode 
• Scalive 
• Metrics 
• Log to fluentd 
https://github.com/xitrum-framework/scalive 
http://www.slideshare.net/georgeosd/scalive 
http://xitrum-framework.github.io/guide/3.18/en/ 
log.html#log-to-fluentd
Thank 
you!
1 of 42

Recommended

JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees) by
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
190.7K views52 slides
Node.js vs Play Framework (with Japanese subtitles) by
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
42.5K views163 slides
Play vs Rails by
Play vs RailsPlay vs Rails
Play vs RailsDaniel Cukier
45.7K views36 slides
Akka and the Zen of Reactive System Design by
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
10K views146 slides
Http4s, Doobie and Circe: The Functional Web Stack by
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
6.3K views33 slides
Scala Matsuri 2016: Japanese Text Mining with Scala and Spark by
Scala Matsuri 2016: Japanese Text Mining with Scala and SparkScala Matsuri 2016: Japanese Text Mining with Scala and Spark
Scala Matsuri 2016: Japanese Text Mining with Scala and SparkEduardo Gonzalez
3.9K views46 slides

More Related Content

What's hot

Spring data requery by
Spring data requerySpring data requery
Spring data requerySunghyouk Bae
1.9K views46 slides
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin by
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSencha
993 views45 slides
Survive JavaScript - Strategies and Tricks by
Survive JavaScript - Strategies and TricksSurvive JavaScript - Strategies and Tricks
Survive JavaScript - Strategies and TricksJuho Vepsäläinen
5.2K views96 slides
Demystifying Oak Search by
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak SearchJustin Edelson
6.3K views57 slides
Mastering Java ByteCode by
Mastering Java ByteCodeMastering Java ByteCode
Mastering Java ByteCodeEcommerce Solution Provider SysIQ
1.7K views50 slides

What's hot(20)

SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin by Sencha
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
Sencha993 views
Survive JavaScript - Strategies and Tricks by Juho Vepsäläinen
Survive JavaScript - Strategies and TricksSurvive JavaScript - Strategies and Tricks
Survive JavaScript - Strategies and Tricks
Juho Vepsäläinen5.2K views
Java EE 6 CDI Integrates with Spring & JSF by Jiayun Zhou
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
Jiayun Zhou3.9K views
Activator and Reactive at Play NYC meetup by Henrik Engström
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
Henrik Engström1.7K views
Building a java tracer by rahulrevo
Building a java tracerBuilding a java tracer
Building a java tracer
rahulrevo645 views
Performance Optimization and JavaScript Best Practices by Doris Chen
Performance Optimization and JavaScript Best PracticesPerformance Optimization and JavaScript Best Practices
Performance Optimization and JavaScript Best Practices
Doris Chen3.6K views
Java FX 2.0 - A Developer's Guide by Stephen Chin
Java FX 2.0 - A Developer's GuideJava FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's Guide
Stephen Chin8.4K views
Node Architecture and Getting Started with Express by jguerrero999
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Express
jguerrero9991.9K views
Softshake 2013: 10 reasons why java developers are jealous of Scala developers by Matthew Farwell
Softshake 2013: 10 reasons why java developers are jealous of Scala developersSoftshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Matthew Farwell2.5K views
Building a real life application in node js by fakedarren
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
fakedarren20.4K views
How and Where in GLORP by ESUG
How and Where in GLORPHow and Where in GLORP
How and Where in GLORP
ESUG2.8K views
Building servers with Node.js by ConFoo
Building servers with Node.jsBuilding servers with Node.js
Building servers with Node.js
ConFoo12.2K views
The DOM is a Mess @ Yahoo by jeresig
The DOM is a Mess @ YahooThe DOM is a Mess @ Yahoo
The DOM is a Mess @ Yahoo
jeresig50.6K views

Similar to Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング

Rich Portlet Development in uPortal by
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortalJennifer Bourey
1.6K views74 slides
Spine.js by
Spine.jsSpine.js
Spine.jswearefractal
1.3K views14 slides
RESTful Web Applications with Apache Sling by
RESTful Web Applications with Apache SlingRESTful Web Applications with Apache Sling
RESTful Web Applications with Apache SlingBertrand Delacretaz
8.2K views43 slides
soft-shake.ch - Hands on Node.js by
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch
2.3K views35 slides
Universal JavaScript by
Universal JavaScriptUniversal JavaScript
Universal JavaScript名辰 洪
1.5K views76 slides
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group) by
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
9.5K views52 slides

Similar to Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング(20)

Rich Portlet Development in uPortal by Jennifer Bourey
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
Jennifer Bourey1.6K views
soft-shake.ch - Hands on Node.js by soft-shake.ch
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch2.3K views
Universal JavaScript by 名辰 洪
Universal JavaScriptUniversal JavaScript
Universal JavaScript
名辰 洪1.5K views
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group) by Doris Chen
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen9.5K views
jQuery Tips Tricks Trivia by Cognizant
jQuery Tips Tricks TriviajQuery Tips Tricks Trivia
jQuery Tips Tricks Trivia
Cognizant3.2K views
WebNet Conference 2012 - Designing complex applications using html5 and knock... by Fabio Franzini
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini1.6K views
Front End Development for Back End Developers - UberConf 2017 by Matt Raible
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
Matt Raible1.4K views
Using and scaling Rack and Rack-based middleware by Alona Mekhovova
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
Alona Mekhovova1.1K views
An Introduction to Tornado by Gavin Roy
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
Gavin Roy9.3K views
vJUG - The JavaFX Ecosystem by Andres Almiray
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX Ecosystem
Andres Almiray3.6K views
Bonnes pratiques de développement avec Node js by Francois Zaninotto
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto5.7K views
GitBucket: The perfect Github clone by Scala by takezoe
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scala
takezoe26.7K views
Ajax tutorial by Kat Roque
Ajax tutorialAjax tutorial
Ajax tutorial
Kat Roque1.4K views
Build Your Own CMS with Apache Sling by Bob Paulin
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
Bob Paulin15.8K views

More from scalaconfjp

脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~ by
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~scalaconfjp
112 views50 slides
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会 by
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会scalaconfjp
72 views20 slides
GraalVM Overview Compact version by
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact versionscalaconfjp
2K views70 slides
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by... by
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...scalaconfjp
842 views37 slides
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視... by
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...scalaconfjp
224 views16 slides
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau by
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan GoyeauScala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeauscalaconfjp
318 views79 slides

More from scalaconfjp(20)

脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~ by scalaconfjp
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
脆弱性対策のためのClean Architecture ~脆弱性に対するレジリエンスを確保せよ~
scalaconfjp112 views
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会 by scalaconfjp
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
Alp x BizReach SaaS事業を営む2社がお互い気になることをゆるゆる聞いてみる会
scalaconfjp72 views
GraalVM Overview Compact version by scalaconfjp
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact version
scalaconfjp2K views
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by... by scalaconfjp
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
Run Scala Faster with GraalVM on any Platform / GraalVMで、どこでもScalaを高速実行しよう by...
scalaconfjp842 views
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視... by scalaconfjp
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
Monitoring Reactive Architecture Like Never Before / 今までになかったリアクティブアーキテクチャの監視...
scalaconfjp224 views
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau by scalaconfjp
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan GoyeauScala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
Scala 3, what does it means for me? / Scala 3って、私にはどんな影響があるの? by Joan Goyeau
scalaconfjp318 views
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti... by scalaconfjp
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
scalaconfjp323 views
Scala ♥ Graal by Flavio Brasil by scalaconfjp
Scala ♥ Graal by Flavio BrasilScala ♥ Graal by Flavio Brasil
Scala ♥ Graal by Flavio Brasil
scalaconfjp315 views
Introduction to GraphQL in Scala by scalaconfjp
Introduction to GraphQL in ScalaIntroduction to GraphQL in Scala
Introduction to GraphQL in Scala
scalaconfjp721 views
Safety Beyond Types by scalaconfjp
Safety Beyond TypesSafety Beyond Types
Safety Beyond Types
scalaconfjp551 views
Reactive Kafka with Akka Streams by scalaconfjp
Reactive Kafka with Akka StreamsReactive Kafka with Akka Streams
Reactive Kafka with Akka Streams
scalaconfjp681 views
Reactive microservices with play and akka by scalaconfjp
Reactive microservices with play and akkaReactive microservices with play and akka
Reactive microservices with play and akka
scalaconfjp2K views
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント by scalaconfjp
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメントScalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
Scalaに対して意識の低いエンジニアがScalaで何したかの話, by 芸者東京エンターテインメント
scalaconfjp810 views
DWANGO by ドワンゴ by scalaconfjp
DWANGO by ドワンゴDWANGO by ドワンゴ
DWANGO by ドワンゴ
scalaconfjp636 views
OCTOPARTS by M3, Inc. by scalaconfjp
OCTOPARTS by M3, Inc.OCTOPARTS by M3, Inc.
OCTOPARTS by M3, Inc.
scalaconfjp1.2K views
Try using Aeromock by Marverick, Inc. by scalaconfjp
Try using Aeromock by Marverick, Inc.Try using Aeromock by Marverick, Inc.
Try using Aeromock by Marverick, Inc.
scalaconfjp1.2K views
統計をとって高速化する
Scala開発 by CyberZ,Inc. by scalaconfjp
統計をとって高速化する
Scala開発 by CyberZ,Inc.統計をとって高速化する
Scala開発 by CyberZ,Inc.
統計をとって高速化する
Scala開発 by CyberZ,Inc.
scalaconfjp963 views
Short Introduction of Implicit Conversion by TIS, Inc. by scalaconfjp
Short Introduction of Implicit Conversion by TIS, Inc.Short Introduction of Implicit Conversion by TIS, Inc.
Short Introduction of Implicit Conversion by TIS, Inc.
scalaconfjp550 views
ビズリーチ x ScalaMatsuri by BIZREACH, Inc. by scalaconfjp
ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
scalaconfjp907 views
sbt, past and future / sbt, 傾向と対策 by scalaconfjp
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策
scalaconfjp4.5K views

Recently uploaded

aATP - New Correlation Confirmation Feature.pptx by
aATP - New Correlation Confirmation Feature.pptxaATP - New Correlation Confirmation Feature.pptx
aATP - New Correlation Confirmation Feature.pptxEsatEsenek1
205 views6 slides
Electronic AWB - Electronic Air Waybill by
Electronic AWB - Electronic Air Waybill Electronic AWB - Electronic Air Waybill
Electronic AWB - Electronic Air Waybill Freightoscope
5 views1 slide
JioEngage_Presentation.pptx by
JioEngage_Presentation.pptxJioEngage_Presentation.pptx
JioEngage_Presentation.pptxadmin125455
8 views4 slides
Benefits in Software Development by
Benefits in Software DevelopmentBenefits in Software Development
Benefits in Software DevelopmentJohn Valentino
5 views15 slides
Page Object Model by
Page Object ModelPage Object Model
Page Object Modelartembondar5
6 views5 slides
Automated Testing of Microsoft Power BI Reports by
Automated Testing of Microsoft Power BI ReportsAutomated Testing of Microsoft Power BI Reports
Automated Testing of Microsoft Power BI ReportsRTTS
10 views20 slides

Recently uploaded(20)

aATP - New Correlation Confirmation Feature.pptx by EsatEsenek1
aATP - New Correlation Confirmation Feature.pptxaATP - New Correlation Confirmation Feature.pptx
aATP - New Correlation Confirmation Feature.pptx
EsatEsenek1205 views
Electronic AWB - Electronic Air Waybill by Freightoscope
Electronic AWB - Electronic Air Waybill Electronic AWB - Electronic Air Waybill
Electronic AWB - Electronic Air Waybill
Freightoscope 5 views
JioEngage_Presentation.pptx by admin125455
JioEngage_Presentation.pptxJioEngage_Presentation.pptx
JioEngage_Presentation.pptx
admin1254558 views
Automated Testing of Microsoft Power BI Reports by RTTS
Automated Testing of Microsoft Power BI ReportsAutomated Testing of Microsoft Power BI Reports
Automated Testing of Microsoft Power BI Reports
RTTS10 views
FOSSLight Community Day 2023-11-30 by Shane Coughlan
FOSSLight Community Day 2023-11-30FOSSLight Community Day 2023-11-30
FOSSLight Community Day 2023-11-30
Shane Coughlan7 views
Advanced API Mocking Techniques Using Wiremock by Dimpy Adhikary
Advanced API Mocking Techniques Using WiremockAdvanced API Mocking Techniques Using Wiremock
Advanced API Mocking Techniques Using Wiremock
Dimpy Adhikary5 views
Supercharging your Python Development Environment with VS Code and Dev Contai... by Dawn Wages
Supercharging your Python Development Environment with VS Code and Dev Contai...Supercharging your Python Development Environment with VS Code and Dev Contai...
Supercharging your Python Development Environment with VS Code and Dev Contai...
Dawn Wages5 views
ADDO_2022_CICID_Tom_Halpin.pdf by TomHalpin9
ADDO_2022_CICID_Tom_Halpin.pdfADDO_2022_CICID_Tom_Halpin.pdf
ADDO_2022_CICID_Tom_Halpin.pdf
TomHalpin95 views
Understanding HTML terminology by artembondar5
Understanding HTML terminologyUnderstanding HTML terminology
Understanding HTML terminology
artembondar57 views
Bootstrapping vs Venture Capital.pptx by Zeljko Svedic
Bootstrapping vs Venture Capital.pptxBootstrapping vs Venture Capital.pptx
Bootstrapping vs Venture Capital.pptx
Zeljko Svedic15 views
How to build dyanmic dashboards and ensure they always work by Wiiisdom
How to build dyanmic dashboards and ensure they always workHow to build dyanmic dashboards and ensure they always work
How to build dyanmic dashboards and ensure they always work
Wiiisdom14 views
How Workforce Management Software Empowers SMEs | TraQSuite by TraQSuite
How Workforce Management Software Empowers SMEs | TraQSuiteHow Workforce Management Software Empowers SMEs | TraQSuite
How Workforce Management Software Empowers SMEs | TraQSuite
TraQSuite6 views

Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング

  • 2. Ngoc Dao https://github.com/ngocdaothanh Takeharu Oshida https://github.com/georgeOsdDev http://mobilus.co.jp/
  • 3. What is Xitrum? Xitrum is an async and clustered ! Scala web framework and HTTP(S) server ! on top of Netty, Akka
  • 4. Why you should use Xitrum? • Featureful! • Easy to use! • High performance Scala, Netty, and Akka are fast! • Scalable Can scale to a cluster of servers using Akka cluster and/or Hazelcast
  • 5. Homepage: http://xitrum-framework.github.io/ (there are various demos) Guides (English, Japanese, Russian): http://xitrum-framework.github.io/guide.html (Korean version is in progress) ! Community (Google Group): https://groups.google.com/forum/#!forum/ xitrum-framework
  • 6. Where Xitrum is used? KONNECT (Messaging Service)! http://mobilus.co.jp/konnect/! ! KONNECT can be used in mobile games, mobiles apps, SNS websites etc. Xitrum is also being used in France, Korea, Russia, Singapore etc.
  • 8. 2010-2013 Xitrum 1.x-2.x http://bit.ly/xitrum13 2014 Xitrum 3.x • Netty 4.x • Swagger • Component • FileMonitor, i18n • CORS • WebJARs • Glokka • Agent7 (autoreload classes on change) ! ! http://bit.ly/xitrum-changelog !
  • 10. Client Netty Async Dispatch request Action FutureAction ActorAction Akka Xitrum I/O thread pool to accept requests and reply responses Thread pool to run FutureAction and ActorAction Client Run directly on Netty I/O thread Netty handler Netty handler Netty handler Netty handler Xitrum Your program
  • 12. Client Client Client Akka cluster (code)! Hazelcast (data) Client Netty Xitrum A FA AA Akka Netty Xitrum A FA AA Akka Server N Server N+1
  • 13. Embed Xitrum object MyApp { def main(args: Array[String]) { ... // Somewhere in your app xitrum.Server.start() ... } 1. Collect routes! } ! 2. Start HTTP/HTTPS servers
  • 14. Action example import xitrum.Action import xitrum.annotation.GET ! @GET("hello") class MyAction extends Action { def execute() { respondText("Hello") } } FutureAction! ActorAction
  • 15. Annotations: Scala vs Java Scala: @GET("matsuri", "festival") Java: @GET(Array("matsuri", "festival")) ! Scala: case class GET(paths: String*) extends scala.annotation.StaticAnnotation ! Java: public @interface GET { String[] value(); }
  • 16. Benefits of using annotations Routes in .class and .jar in classpath are automatically collected and merged. A.class B.class lib1.jar lib2.jar Routes
  • 17. Problem with annotations Collecting routes from .class and .jar files is slow.! ! Solutions:! • In development mode, routes in .class and .jar files that are not in the current working directory are cached to file routes.cache. • To avoid loading lots of classes, don't collect routes from: java.xxx, javax.xxx, scala.xxx, sun.xxx, com.sun.xxx
  • 18. Annotations defined by Xitrum:! http://bit.ly/xitrum-annotations! ! Lib to scan classes in classpath to collect routes:! https://github.com/xitrum-framework/sclasner
  • 19. Demo overview GET / GET /chat username password login Hello ! Hello! How are you? Fine message send POST /login SockJS /connect https://github.com/xitrum-framework/matsuri14
  • 20. Demo overview • Simple HTTP CRUD with MongoDB POST /admin/user GET /admin/user GET /admin/user/:userId PUT /admin/user/:userId DELETE /admin/user/:userId PUT/PATCH/DELETE can be emulated via POST with _method=PUT/PATCH/DELETE ! • API documentation with Swagger
  • 21. DB Cluseter Xitrum1 Akka Hazelcast Xitrum2 Akka Hazelcast Xitrum3 Cluster LB (HAProxy, Nginx, Route53 etc.) NoSQL RDB Other services Akka Hazelcast https://github.com/xitrum-framework/glokka https://github.com/xitrum-framework/xitrum-hazelcast
  • 23. Getting started with xitrum-new skeleton https://github.com/xitrum-framework/xitrum-new https://github.com/xitrum-framework/xitrum-scalate
  • 24. @GET("admin") class AdminIndex extends Action { def execute() { // Get all users val users = User.listAll() // Pass users to view template at("users") = users ! // Response respons view with template respondView() } } ActorAction FutureAction Action
  • 25. - import matsuri.demo.action._! - import matsuri.demo.model.User! ! div.row#usersTable! table.table.table-striped#messageTable! thead! tr.bg-primary! View • Scalate template with jade (mustache, scaml, or ssp) • "at" function • i18n with GNU gettext th.col-xs-2 =t("Name")! th.col-xs-2 =t("Age")! th.col-xs-2 =t("Desc")! th.col-xs-2 =t("Created time")! th.col-xs-2 =t("Updated time")! th.col-xs-2 =t("Last login time")! tbody! - for (user <- at("users").asInstanceOf[List[User]])! tr! th! a(href={url[AdminUserShow](("name", user.name))}) = user.name! th = user.age! th = user.desc! th = user.createdAtAsStr! th = user.updatedAtAsStr! th = user.lastLoginAsStr
  • 26. └── src └── scalate └── matsuri └── demo └── action ├── AdminIndex.jade └── DefaultLayout.jade package matsuri.demo.action ! import xitrum.Action ! trait DefaultLayout extends Action { override def layout = renderViewNoLayout[DefaultLayout]() } Layout
  • 27. !!! 5 html head != antiCsrfMeta != xitrumCss ! meta(content="text/html; charset=utf-8" http-equiv="content-type") title ScalaMatsuri2014 Xitrum Demo ! link(rel="shortcut icon" href={publicUrl("favicon.ico")}) link(type="text/css" rel="stylesheet" media="all" href={webJarsUrl("bootstrap/3.2.0/css", "bootstrap.css", "bootstrap.min.css")}) link(type="text/css" rel="stylesheet" media="all" href={publicUrl("app.css")}) ! body .container h1 ! #flash !~ jsRenderFlash() != renderedView Layout ! != jsDefaults script(src={webJarsUrl("bootstrap/3.2.0/js", "bootstrap.js", "bootstrap.min.js")}) script(src={webJarsUrl("underscorejs/1.6.0", "underscore.js", "underscore-min.js")}) != jsForView
  • 28. form(role="form" method="post" action={url[AdminUserCreate]}) != antiCsrfInput div.modal-header button.close(type="button" data-dismiss="modal") Form span(aria-hidden="true") &times; span.sr-only =t("Close") h4.modal-title#myModalLabel =t("Create New User") div.modal-body div.form-group label(for="newUserName") =t("Name") input.form-control#newUserName(name="name" type="text" • "url" function • jquery-validation • Anti csrf token placeholder={t("Enter Name")} minlength=5 maxlenght=10 required=true) div.form-group label(for="newUserPass") =t("Password") input.form-control#newUserPass(name="password" type="password" placeholder={t("Enter Password")} minlength=8 required=true) ! div.modal-footer button.btn.btn-default(type="button" data-dismiss="modal") = t("Cancel") button.btn.btn-primary(type="submit") = t("Save")
  • 29. @POST("admin/user") class AdminUserCreate extends AdminAction { def execute() { // Get request paramaters val name = param("name") val password = param("password") // Optional parameters val age = paramo[Int]("age") val desc = paramo("desc") ! Required.exception("name", name) Required.exception("password", password) ! User.create(name, password, age, desc) flash(t("Success")) redirectTo[AdminIndex]() } Get request params with param(s) and param(o)
  • 30. object SVar { object isAdmin extends SessionVar[Boolean] } Use before filter to check trait AdminFilter { this: Action => ! beforeFilter { if (SVar.isAdmin.isDefined) true else authBasic() } ! private def authBasic(): Boolean = { basicAuth(Config.basicAuth.realm) { (username, password) => if (username == Config.basicAuth.name && password == Config.basicAuth.pass) { SVar.isAdmin.set(true) true } else { false } } } authentication info in session
  • 31. @Swagger( Swagger.Summary("Create User"), Swagger.Response(200, "status = 0: success, 1: failed to create user"), Swagger.Response(400, "Invalid request parameter"), Swagger.StringForm("name"), Swagger.StringForm("password"), Swagger.OptIntForm("age"), Swagger.OptStringForm("desc") ) API doc • /xitrum/swagger • /xitrum/swagger-ui • Create test client with Swagger-codegen https://github.com/wordnik/swagger-ui https://github.com/wordnik/swagger-codegen https://github.com/wordnik/swagger-spec
  • 32. @GET("login", "") class LoginIndex extends DefaultLayout { def execute() { respondView() } } ! @POST("login") class Login extends Action { def execute() { session.clear() val name = param("name") val password = param("password") ! User.authLogin(name, password) match { case Some(user) => SVar.userName.set(user.name) redirectTo[ChatIndex]() ! case None => flash(t(s"Invalid username or password")) redirectTo[LoginIndex]() } } } Login
  • 33. jsAddToView( "var url = '" + sockJsUrl[ChatAction] + "';" + """ var socket; var initSocket = function() { socket = new SockJS(url); socket.onopen = function(event) { console.log("socket onopen", event.data); socket.send(JSON.parse({"msg":"Hello Xitrum"})); }; socket.onclose = function(event) {console.log("socket onclose", event.data);}; socket.onmessage = function(event) {console.log("socket onmessage", event.data);}; }; initSocket(); """ ) != jsDefaults script(src={webJarsUrl("bootstrap/3.2.0/js", "bootstrap.js", "bootstrap.min.js")}) script(src={webJarsUrl("underscorejs/1.6.0", "underscore.js", "underscore-min.js")}) != jsForView • jsAddToView/jsForView • sockJsUrl • webJarsUrl Create chat client with SockJS
  • 34. import xitrum.{SockJsAction, SockJsText} import xitrum.annotation.SOCKJS ! @SOCKJS("connect") class ChatAction extends SockJsAction with LoginFilter { def execute() { context.become { SockJsAction (an Actor) case SockJsText(text) => SeriDeseri.fromJson[Map[String, String]](text) match { case Some(jsonMap) => // echo respondSockJsText(SeriDeseri.toJson(jsonMap)) case None => log.warn(s"Failed to parse request: $text") respondSockJsText("invalid request") } Create } • SockJsAction • SockJsText/respondSockJsText • SeriDeseri.fromJson[T] / SeriDeseri.toJson(ref:AnyRef)
  • 35. Lookup singleton Actor with Glokka Xitrum socket open Client HubActor trait Hub extends Actor { protected var clients = Seq[ActorRef]() def receive = { case Subscribe(option) => clients = clients :+ sender case Unsubscribe(option) => clients = clients.filterNot(_ == sender) case Terminated(client) => clients = clients.filterNot(_ == client) case ignore => } import glokka.Registry object Hub { val KEY_PROXY = "HUB_PROXY" val actorRegistry = Registry.start(Config.actorSystem, KEY_PROXY) } ! def lookUpHub(key: String, hubProps: Props, option: Any = None) { Hub.actorRegistry ! Registry.Register(key, hubProps) context.become { hub ! Subscribe ChatAction ChatAction ChatAction ChatAction case result: Registry.FoundOrCreated => result.ref ! Subscribe } } Client Client Client https://github.com/xitrum-framework/glokka
  • 36. Messaging overview SockJsText! (socket.send) hub ! Push(msg) clients.foreach { _ ! Publish(msg)} respondSockJSText(msg:String) Client ChatAction HubActor socket.onmessage SockJsText hub ! Pull(msg) case class Done (option: Map[String, Any] = Map.empty) // Hub -> Action case class Publish(option: Map[String, Any] = Map.empty) // Hub -> Action case class Pull (option: Map[String, Any] = Map.empty) // Action -> Hub case class Push (option: Map[String, Any] = Map.empty) // Action -> Hub https://github.com/georgeOsdDev/glokka-demo ChatAction Client ChatAction ChatAction Client Client respondSockJSText(msg:String) sender ! Done(msg) Client ChatAction HubActor respondSockJSText(msg:String) sender ! Done(msg) socket.onmessage
  • 37. Cluster config for Hazelcast hazelcastMode = clusterMember ! cache = xitrum.hazelcast.Cache #cache { # # Simple in-memory cache # "xitrum.local.LruCache" { xitrum.conf # maxElems = 10000 # } • Xitrum-hazelcast #} • Shared Session • Shared Cache ! session { store = xitrum.hazelcast.Session # Store sessions on client side #store = xitrum.scope.session.CookieSessionStore
  • 38. akka { loggers = ["akka.event.slf4j.Slf4jLogger"] logger-startup-timeout = 30s ! actor { provider = "akka.cluster.ClusterActorRefProvider" } ! # This node remote { log-remote-lifecycle-events = off netty.tcp { hostname = "127.0.0.1" port = 2551 # 0 means random port } } ! cluster { seed-nodes = [ "akka.tcp://xitrum@127.0.0.1:2551", "akka.tcp://xitrum@127.0.0.1:2552"] ! auto-down-unreachable-after = 10s } } Cluster config for Akka
  • 39. Live class reload during development https://github.com/xitrum-framework/agent7 https://github.com/dcevm/dcevm java -javaagent:`dirname $0`/agent7-1.0.jar -XXaltjvm=dcevm -Xms256M -Xmx512M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/sbt-launch-0.13.5.jar "$@" https://github.com/xitrum-framework/xitrum-package
  • 40. Package project for deploying to production server https://github.com/xitrum-framework/xitrum-package sbt/sbt xitrum-package
  • 41. Monitor Xitrum in production mode • Scalive • Metrics • Log to fluentd https://github.com/xitrum-framework/scalive http://www.slideshare.net/georgeosd/scalive http://xitrum-framework.github.io/guide/3.18/en/ log.html#log-to-fluentd