node.jsでchatアプリっぽいもの作るメモに引き続き、第2弾。
socket.ioを使って、あるtextareaで編集した内容を出来るだけリアルタイムに別のページに反映させるもの、を作ってみた。誰かがライブでtextareaで書いているコードをwebからみんなが見られる、的な。
https://github.com/sugyan/node-socket-sample にコード置いておきます。
サーバー側jsはこんなカンジで。
var express = require('express');
var app = express.createServer();
var ejs = require('ejs');
var io = require('socket.io');
var port = 3000;
app.set('view engine', 'ejs');
app.set('view options', { layout: false });
app.set('views', __dirname + '/views');
app.get('/editor', function(req, res) {
console.log('/editor');
res.render('editor', { locals: { port: port } });
});
app.get('/viewer', function(req, res) {
console.log('/viewer');
res.render('viewer', { locals: { port: port } });
});
app.listen(port);
var socket = io.listen(app);
socket.on('connection', function(client) {
client.on('message', function(msg) {
client.broadcast(msg);
});
client.on('disconnect', function() {
console.log('disconnect');
});
});
console.log('Server running at http://127.0.0.1:' + port + '/');
editorページとviewerページを用意。httpのポートだけ任意に変えられるようにしています。
socket.ioは、「editorからのみmessageが来る」「viewerからはmessage受け取らずに送るだけ」という前提で、送信されてくるものをbroadcastするだけ。
で、"views/editor.ejs"
<html>
<head>
<title>editor</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.4.4");</script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
$(function() {
var socket = new io.Socket(null, { port: <%= port %> });
socket.connect();
socket.on('connect', function() {
console.log('connect');
});
socket.on('disconnect', function(){
console.log('disconnect');
});
var code_prev = $('#code').val();
var loop = function() {
var code = $('#code').val();
if (code_prev != code) {
socket.send(code);
code_prev = code;
}
setTimeout(loop, 100);
};
loop();
});
</script>
<style type="text/css">
textarea#code {
width: 500px;
height: 200px;
}
</style>
</head>
<body>
<textarea id="code"></textarea>
</body>
</html>
100msごとにtextareaの内容をチェックし、前回チェックしたときから変更されていればsocketにsendします。差分だけとりだして、とかやろうとすると面倒なのでとりあえず内容をすべて丸投げ。
"views/viewer.ejs"では
<html>
<head>
<title>viewer</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.4.4");</script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
$(function() {
var socket = new io.Socket(null, { port: <%= port %> });
socket.connect();
socket.on('connect', function() {
console.log('connect');
});
socket.on('disconnect', function() {
console.log('disconnect');
});
socket.on('message', function(msg) {
$('#code').text(msg);
});
});
</script>
</head>
<body>
<pre id="code" />
</body>
</html>
socketから送られて来たものをそのまま反映するだけ。
これで、起動して片方では"/viewer"を開きつつ、別窓から"/editor"を開いてtextareaを編集すると…
結構リアルタイムに編集内容が反映されます。たのしい。
しばらくは
http://www1216u.sakura.ne.jp:3000/viewer
http://www1216u.sakura.ne.jp:3000/editor
で動かしておきますので壊さない程度に遊んでみて下さい。session管理とかしていないので色んな人がeditor側を弄ると大変なことになりそうだけど…w