SockJS+CoffeeScript+ Node.js组合使用指南

12年前
I recently did a blog post on Socket.IO. Today I’ll go over an alternative called SockJS. According to the SockJS website: “SockJS is a browser JavaScript library that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server”. Within the SockJS family there are server-side counterparts like the one for Node.js. As a side note – SockJS-Node is actually written in CoffeeScript

Note: I’m going to borrow from the examples provided and convert those to CoffeeScript.

I like using ExpressJS so the example using Express caught my eye. Lets take this example and turn it into a CoffeeScript project.

The original server code in JavaScript looks like this:

var express = require('express');  var sockjs  = require('sockjs');    // 1. Echo sockjs server  var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.3.min.js"};    var sockjs_echo = sockjs.createServer(sockjs_opts);  sockjs_echo.on('connection', function(conn) {      conn.on('data', function(message) {          conn.write(message);      });  });    // 2. Express server  var app = express.createServer();  sockjs_echo.installHandlers(app, {prefix:'/echo'});    console.log(' [*] Listening on 0.0.0.0:9999' );  app.listen(9999, '0.0.0.0');    app.get('/', function (req, res) {      res.sendfile(__dirname + '/index.html');  });

Converting this to CoffeeScript is trivial using tools like this one. Here is the result:

express = require("express")  sockjs = require("sockjs")    sockjs_opts = sockjs_url: "http://cdn.sockjs.org/sockjs-0.3.min.js"  sockjs_echo = sockjs.createServer(sockjs_opts)    sockjs_echo.on "connection", (conn) ->   conn.on "data", (message) ->       conn.write message    app = express.createServer()    sockjs_echo.installHandlers app,   prefix: "/echo"    console.log " [*] Listening on 0.0.0.0:9999"    app.listen 9999, "0.0.0.0"  app.get "/", (req, res) ->   res.sendfile __dirname + "/index.html"

Express creates the server and we call installHandlers passing in the app server so we can listen and answer any incoming requests on the echo path.

From the OS X Terminal I’m going to create a new folder and then install the dependencies (you can also call the package.json if you wish). If you have CoffeeScript installed globally then you can ignore the line that installs CoffeeScript. Make sure you have Node.js (with NPM) installed.

$ mkdir SockJSDemo && cd SockJSDemo  $ npm install coffee-script  $ npm install express  $ npm install sockjs

Take the above CoffeeScript that we converted and save it in the new folder. Call the file server.coffee

The example index.html file uses JavaScript inside of it. Typically, this is indeed how you will deploy a production app, however, did you know you can use CoffeeScript in the client side files as well? As a demo, I’ll show you how to do this. Please keep in mind that running CoffeeScript in the browser does make things a little slower and there are other side effects to be aware of according to the CoffeeScript website: “your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the window object”

We will now take the script from the index.html file and convert it to use CoffeeScript:

<!doctype html>  <html><head>      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>      <script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>      <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>      <style>        .box {            width: 300px;            float: left;            margin: 0 20px 0 20px;        }        .box div, .box input {            border: 1px solid;            -moz-border-radius: 4px;            border-radius: 4px;            width: 100%;            padding: 0px;            margin: 5px;        }        .box div {            border-color: grey;            height: 300px;            overflow: auto;        }        .box input {            height: 30px;        }        h1 {            margin-left: 30px;        }        body {            background-color: #F0F0F0;            font-family: "Arial";        }      </style>  </head><body lang="en">      <h1>SockJS Express example</h1>        <div id="first" class="box">        <div></div>        <form><input autocomplete="off" value="Type here..."></input></form>      </div>        <script type="text/coffeescript">    sockjs_url = "/echo"    sockjs = new SockJS(sockjs_url)        $("#first input").focus()    div = $("#first div")    inp = $("#first input")    form = $("#first form")    print = (m, p) ->     p = (if (p is 'undefined') then "" else JSON.stringify(p))     div.append $("<code>").text(m + " " + p)     div.append $("<br>")     div.scrollTop div.scrollTop() + 10000        sockjs.onopen = ->       print "[*] open", sockjs.protocol        sockjs.onmessage = (e) ->       print "[.] message", e.data        sockjs.onclose = ->       print "[*] close"        form.submit ->     print "[ ] sending", inp.val()     sockjs.send inp.val()     inp.val ""     false      </script>  </body></html>

Save this file as index.html in the same location as the server.coffee file. The real important thing in the above code are these lines:

<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>

Note: You should copy the above file to your servers for production, don’t rely on GitHub to serve this file!

<script type="text/coffeescript">

We now have everything to run this.

$ coffee server.coffee

Results (in Google Chrome):

F.Y.I – I’m currently reading a very good CoffeeScript book which is available on Amazon: