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