socket.io.jsxを作りました。

このエントリは、JSX Advent Calendar 2013の18日目です。

socket.ioの1.0が出ると言われて、出ないまま早一年半経ちました。早いですね。

まぁでもsocket.ioはNode.jsのムーブメントを起こしたモジュールの一つであることに疑いはなく、
socket.ioをJSXから使いたいというニーズもそろそろ弊社から上がる頃ではないかと思い、socket.io.jsxを作りました。

socket.io.jsx

https://npmjs.org/package/socket.io.jsx

https://github.com/yosuke-furukawa/socket.io.jsx

使い方

何はともあれ npmのインストールから。

$ npm init
$ npm install socket.io socket.io.jsx --save

あとは、こんな感じで書くとsocket.ioが使えるようになります。

import "socket.io.jsx";

class _Main {
  static function main(args : string[]) : void {
    var io = SocketIO.listen(5000);
    io.sockets.on("connection", function(socket : Socket) {
      socket.emit("news", {"hello":"world"});
      socket.on("my other event", function(data) {
        log data;
      });
    });
  }
}

express.jsxとsocket.io.jsxを使う。

さて、Node.jsを使うときのパターンとしてよく出てくる組み合わせのexpressとsocket.ioをjsxから使うチュートリアルも説明しておきます。

一応ここにサンプルコードを用意しました。

yosuke-furukawa/socket.io.jsx_sample · GitHub

これをcloneして使えば、expressとsocket.ioを利用したサンプルは使えるようになるかと思いますが、ちょっとだけ説明しようかと。

main.jsx (サーバーサイドのコード)
import "socket.io.jsx";
import "express.jsx";
import "nodejs/*.jsx";

// http_expressという形でexpressのApplicationクラスをcreateServerで作成できるようにする。
native class http_express extends http {
        static function createServer(
          app : Application
        ) : HTTPServer;
} = "require('http')";

class _Main {
  static function main(args : string[]) : void {
    // express.create()でApplicationオブジェクトが返る。
    var app = express.create();
    // アプリケーションオブジェクトのstaticファイルとしてpublic以下を追加する。
    app.use(express.static_(path.join(node.__dirname, 'public')));
    // serverオブジェクトを受け取る
    var server = http_express.createServer(app);

    server.listen(3000);
    
    // HTTPServerクラスをlistenに入れる。
    // この辺りはsocket.ioとほぼ同じ
    var io = SocketIO.listen(server);
    io.sockets.on("connection", function(socket : Socket) {
      socket.emit("news", {"hello":"world"});
      socket.on("my other event", function(data) {
        log data;
      });
    });
  }
}
public/client.jsx クライアント側
import "js.jsx";
import "socket.io-webclient.jsx";

class _Main {
  static function main(args : string[]) : void {
    // socket.io.jsのioオブジェクトをSocketIOWebClientクラスにキャストして使う。
    var io = js.global["io"] as __noconvert__ SocketIOWebClient;
    // 後はほとんどsocket.ioと同じ。
    var socket = io.connect('http://localhost');
    socket.on('news', function (data) {
      log data;
      socket.emit('my other event', { my: 'data' });
    });
  }
}

こんな感じで作成しておき、public/index.htmlを以下のようにしておきます。

public/index.html
<html>
<script src="/socket.io/socket.io.js"></script>
<script src="/client.js"></script>
</html>
Gruntfile.js
module.exports = function(grunt) {
  var pkg = grunt.file.readJSON('package.json');
  grunt.initConfig({
    jsx: {
      build_server: {
        src: "main.jsx",
        dest: "main.js",
        add_search_path: ["node_modules/express.jsx/lib", "node_modules/socket.io.jsx/src", "nodejs.jsx/lib"],
        executable : "node",
      },
      build_client: {
        src: "public/client.jsx",
        dest: "public/client.js",
        add_search_path: ["node_modules/socket.io.jsx/src"],
        executable : "web",
      },
      test: {
        src: grunt.option('target') || 't/**/*.jsx',
        add_search_path: ["src", "nodejs.jsx/lib"],
        executable : "node",
        test : true,
      },
    },
  });

  grunt.loadNpmTasks("grunt-jsx");

  grunt.registerTask('test', ['jsx:test']);
  grunt.registerTask('build', ['jsx:build_server', 'jsx:build_client']);
}
ここまで作れば、あとはgrunt buildでビルドするだけ
$ grunt build
$ open http://localhost:3000/


実行するとコンソールにメッセージを送れることが確認できると思います。

enjoy jsx life!!!!!