Awed’s blog

雑感とか

WAMPをいじってみた

WAMPって?

HTML5のサーバ通信の仕様としてWebSocketという仕様があるんですが、これは名前の通りソケットを作れるだけなので、これの上にメッセージプロトコルを用意しようというプロジェクトです。WebSocketに限らず使えるプロトコルではあるんですが、一番推奨はWSということのようです。

  • まずNode.jsをいれます。普通にインストールするだけなので説明は割愛
  • wampのルータとクライアントにOrangeのオープンソースプロジェクトであるwamp.rtを使ってみましょう。
  • GitHubからソースコードをダウンロードして展開します。
  • index.htmlをこんな感じで作成します。ついでにwampというディレクトリもmkdirしましょう。
  • さらにautobahn.jsをダウンロードしてwampディレクトリにいれます。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>wamp samples</h1>
<a href="wamp/">wamp</a>
</body>

 

  • 次にindex.jsを書き換えます。 

 

var http = require('http'); // HTTPサーバーをnode.jsに要求
var port = process.env.PORT || 5000; // portは5000

var httpServer = http.createServer(function(req, res) {

var fname = '.';
if(req.url=='/')
fname += '/index.html';
else if(req.url=='/wamp' || req.url=='/wamp/')
fname += '/wamp/wamp.html';
else
fname += req.url;

var file;
try {
file = require('fs').readFileSync(fname);
} catch(e) {
file = null;
}
if (file != null) {
var mimeType = 'text/html';
if (fname.lastIndexOf('.jgz') >= 0 || fname.lastIndexOf('.js') >= 0)
mimeType = 'text/javascript';
res.writeHead(200, { 'Content-Type': mimeType});
res.end(file);
} else {
res.writeHead(404);
res.end();
}
}).listen(port);

var WAMP = require('./wamp/wamp.js');
var wamp = new WAMP(httpServer, '/wamp/'); // HTTPサーバー生成

  • 次にルータ用のjsを用意します。wamp.jsというファイルを/wampに作ります。

//
// WAMP router
//

module.exports = wamp;

WAMPRT_TRACE = true;

var Router = require('./wamp.rt');


function wamp(httpServer, path) {

function onRPCRegistered(uri) {
console.log('onRPCRegistered RPC registered', uri);
}

function onRPCUnregistered(uri) {
console.log('onRPCUnregistered RPC unregistered', uri);
}


var app = new Router(
{ "server": httpServer,
"path": path,
handleProtocols: function(protocols,cb) {
console.log(protocols);
cb(true,protocols[0]);
//cb(false);
}

}
);
app.on('RPCRegistered', onRPCRegistered);
app.on('RPCUnregistered', onRPCUnregistered);

}

  •  呼び出し側(CALLER)のhtmlコードwamp.htmlも同じディレクトリに書きましょう。

<!DOCTYPE html>
<html>
<head>
<script src="autobahn.min.jgz"></script>
<script script="text/javascritp">
function onLoad() {
var href = document.location.href;
var url = href.replace('http', 'ws');

var calcTag = document.getElementById('calcTag');
var op1Tag = document.getElementById('op1Tag');
var op2Tag = document.getElementById('op2Tag');
var respTag = document.getElementById('respTag');
calcTag.style.backgroundColor = 'rgb(221, 221, 221)';

console.log("ws url=" + url);
var connection = new autobahn.Connection({
url: url,
realm: 'realm1'
});

connection.onopen = function (session) {
console.log('onopen');

calcTag.addEventListener('click', function() {
session.call('com.myapp.calc', [op1Tag.value, op2Tag.value]).then(
function (res) {
var msg = res;
console.log(msg);
respTag.value = msg;
}
);
});
};

connection.onclose = function (reason, details) {
console.log("onclose", reason, details);
};

connection.open();
}
</script>
<style type="text/css">
h1 {
font-size: 36px;
}
button,label,input {
font-size: 24px;
display: block;
width: 100px;
float: left;
margin-bottom: 10px;
}
label {
padding-left: 20px;
text-align: right;
padding-right: 10px;
}
input {
width: 100px;
}
br { clear: left; }
</style>
</head>
<body onload='onLoad()'>
<h1>WAMP Test (CALLER)</h1>
<div>
<button id="calcTag">Calc</button>
<label>Op1</label>
<input id="op1Tag" type="text"/>
<label>Op2</label>
<input id="op2Tag" type="text"/>
<label>Result</label>
<input id="respTag" type="text"/>
</div>
</body>
</html>

  •  最後に呼び出され側(CALLEE)のhtmlファイルwamp-callee.htmlを作ります。ファイル名をハードコードしていて汚いですが…まぁとりあえず。

<!DOCTYPE html>
<html>
<head>
<script src="autobahn.min.jgz"></script>
<script script="text/javascritp">
function onLoad() {
var href = document.location.href;
var url0 = href.replace('http','ws');
var url = url0.replace('wamp-callee.html','');

var resTag = document.getElementById('resTag');

console.log("ws url=" + url);
var connection = new autobahn.Connection({
url: url,
realm: 'realm1'
});

connection.onopen = function (session) {
console.log('onopen');

function calc(args) {
console.log(args);
var val = Number(args[0]) + Number(args[1])
resTag.value = val;
return val;
}
session.register('com.myapp.calc', calc);
console.log('com.myapp.calc registered');
};

connection.onclose = function (reason, details) {
console.log("onclose", reason, details);
};

connection.open();
}
</script>
<style type="text/css">
h1 {
font-size: 36px;
}
button,label,input {
font-size: 24px;
display: block;
width: 100px;
float: left;
margin-bottom: 10px;
}
label {
padding-left: 20px;
text-align: right;
padding-right: 10px;
}
input {
width: 800px;
}
br { clear: left; }
</style>
</head>
<body onload='onLoad()'>
<h1>WAMP Test (CALLEE)</h1>
<div>
<label>Result</label>
<input id="resTag" type="text"/>
</div>
</body>
</html>

  •  二つのhtmlファイルwamp.htmlとwamp-callee.htmlをそれぞれブラウザで開くとwamp.htmlで入力した数字をwamp-callee.htmlで足し算して、結果をwamp.htmlに返すという処理が確認できます。
  • 呼び出され側のHTMLファイルwamp-callee.htmlの足し算Procedure calc(args)をwamp.html側からリモートで呼び出しているのでRPCが実現できていますね。
  • wamp.rtとautobahn.jsを使うとWebSocketサーバ上で簡単にこのような文書間通信ができるわけです。