Node.jsの紹介
「別にサーバサイドまでJavaScriptで書きたいとは思わないんだけど」で玉砕
- ハードウェアの性能に関わらず、同時接続するクライアント数に限界がきてしまう問題
- 原因は複合的だが、主な原因の1つはスレッド数の増大
- Ajax/Cometが出てきて注目された
| 種別 | サイクル | メートル換算 |
|---|---|---|
| CPU L1キャッシュ | 3 | 3m |
| CPU L2キャッシュ | 14 | 14m |
| メモリ | 250 | 250m |
| ディスク | 41,000,000 | 地球1周 |
| ネットワーク | 240,000,000 | 地球6周 |
このようなプラットフォームをどの言語向けに提供すべきか
既存のI/Oライブラリが存在しないため、0からすべてがノンブロッキングな世界を作り上げることができる環境
Node.jsを使う
チャット, ゲーム, コラボレーションツール, etc...
「夜のNode.js」でggr
jQueryなどのJSライブラリを使えるので、スクレイピングが楽チン
$ curl http://nodejs.org/dist/node-v0.4.10.tar.gz | tar xz
$ cd node-v0.4.10
$ ./configure
$ make
$ sudo make install
$ curl http://npmjs.org/install.sh | sudo sh
$ npm install express -g
$ express chat
$ cd chat
$ cat package.json
{
"name": "ChatSample"
, "version": "0.0.1"
, "private": true
, "dependencies": {
"express": "2.4.3"
, "jade": ">= 0.0.1"
, "socket.io": ">= 0.7"
}
}
$ npm install
chat
- public
- stylesheets
- style.css
- images
- javascripts
- views
- layout.jade
- index.jade
- app.js
- package.json
- node_modules
- express
- socket.io
var express = require('express');
var app = module.exports = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
app.get('/', function(req, res){
res.render('index', {
title: 'Express'
});
});
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
h1= title
p Welcome to #{title}
!!!
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body!= body
$ node app.js
http://localhost:3000/
var io = require('socket.io').listen(app);
var chatCount = 0;
var messages = []; // あとで使う
var chat = io.of('/chat').on('connection', function(socket) {
chatCount++;
chat.emit('count', {count: chatCount});
socket.on('message', function(data) {
// ブラウザからチャットテキストを受信した時の処理
});
socket.on('disconnect', function() {
chatCount--;
chat.emit('count', {count: chatCount});
});
});
var chat = io.connect('http://localhost:3000/chat');
chat.on('connect', function() {
chat.on('count', function(data) {
$('#count').text(data.count);
});
chat.on('message', function(data) {
// サーバからチャットテキストを受信した時の処理
});
});
function send() {
// サーバへチャットテキストを送信する処理
}
h1= title
p 現在接続している人は
span#count
人います
#chat
form#form(onsubmit='send(); return false;')
input#name(type='text', placeholder='Name')
input#text(type='text', autocomplete='off')
input(type='submit', value='送信')
function send() {
var name = $('#name').val();
var text = $('#text').val();
if (text && name) {
chat.emit('message', {name: name, text: text});
$('#text').val('');
}
}
var chat = io.of('/chat').on('connection', function(socket) {
//省略(count++の処理)
messages.forEach(function(data) {
socket.emit('message', data);
});
socket.on('message', function(data) {
data.timestamp = new Date().getTime();
chat.emit('message', data);
var length = messages.push(data);
if (length > 100) {
messages.shift();
}
});
//省略(切断時のcount--の処理)
});
chat.on('message', function(data) {
var date = new Date(data.timestamp);
$('#chat').append(
'<div class="chatlog"><p>
+ escape(data.name)
+ ': '
+ escape(data.text)
+ '</p><span class="date">'
+ date.toString()
+ '</span></div>');
$('#chat').scrollTop(1000000);
});
http://miyukki.mesolabs.com/chat
http://github.com/meso/miyukki
ありがとう
ございました
0 / 0