I’ve spent much time recently working with node, and one of the coolest packages I’ve discovered is zappa! It’s a streamlined wrapper for express & socket.io, with a whole bunch of awesome added conveniences…and it’s in coffeescript. Cool!
Ultimately I want to try creating a socket-ized 2 player pong game controlled by mobile device, but this post will concentrate on building a simple app that log’s the mouse movements for 2 connected clients.
1) Install node.
2) Open command prompt/terminal & install zappa with npm:
npm install zappa
3) Create a new coffeescript file called, ‘app.coffee’. We’ll configure our app so that zappa serves jquery and static assets (like css and js files). By default, static assets are served from a ‘public’ folder.
@configure =>
@enable 'serve jquery'
@use 'static' #serves static assets from public folder
4) Next we’ll define a route.
@get '/control' : ->
@render 'control' : layout: no
By default your app will use port 3000. Whenever a client requests ‘http://localhost:3000/control’, a template called ‘control’ will be rendered, and here it is:
@view control: ->
doctype 5
html ->
head ->
link rel: 'stylesheet', href: '/css/style.css'
script src: '/socket.io/socket.io.js'
script src: '/zappa/jquery.js'
script src: '/zappa/zappa.js' #necessary for @client socket
script src: '/client.js'
body ->
canvas id: 'canvas', width : '500', height: '500'
Zappa uses the coffeekup template engine, allowing you to define your html template in coffeescript. You can also use other template engines like Jade, which is my preferred template engine.
5) Last thing to do on the server side is handle socket data. We want to be notified when a player connects or drags their mouse:
@on connection: ->
if playerCount < 2
@client.name = "Player #{playerCount}"
@emit player: @client.name
playerCount++
@on move: ->
console.log("#{@client.name} moved to #{@data}")
6) In order for the socket magic to happen, there needs to be some client side javascript too. Again, zappa makes things all magical and rainbow-ish by letting you write inline coffee which is deployed as javascript (‘client.js’). In order for it to work, the client needs a reference to zappa -> ‘zappa.js’ in your in your html
@client '/client.js': ->
@connect()
@on player: ->
console.log @data
$ =>
isMouseDown = false
canvas = $('#canvas')
canvas.mousedown (e) =>
@emit move : e.pageY
isMouseDown = true
canvas.mouseup -> isMouseDown = false
canvas.mousemove (e) =>
if isMouseDown
@emit move : e.pageY
7) Start your app. Open a terminal window/command prompt.
coffee app.coffee
8 ) Open 2 brower windows, and click & drag in each. You should see something like, ‘player 0 moved to 150′ in the console.
The final code:
playerCount = 0
require('zappa') ->
@configure =>
@enable 'serve jquery'
@use 'static'
#routes
@get '/control' : ->
@render 'control' : layout: no
#inline view templates
@view control: ->
doctype 5
html ->
head ->
link rel: 'stylesheet', href: '/css/style.css'
script src: '/socket.io/socket.io.js'
script src: '/zappa/jquery.js'
script src: '/zappa/zappa.js'
script src: '/client.js'
body ->
canvas id: 'canvas', width : '500', height: '500'
@on connection: ->
if playerCount < 2
@client.name = "Player #{playerCount}"
@emit player: @client.name
playerCount++
@on move: ->
console.log("#{@client.name} moved to #{@data}")
@client '/client.js': ->
@connect()
@on player: ->
console.log @data
$ =>
isMouseDown = false
canvas = $('#canvas')
canvas.mousedown (e) =>
@emit move : e.pageY
isMouseDown = true
canvas.mouseup -> isMouseDown = false
canvas.mousemove (e) =>
if isMouseDown
@emit move : e.pageY
Download files.