"ãªã¢ã«ã¿ã¤ã Web" ã«é¢ãããã©ã¯ãã£ã¹ã®ã¢ã¦ãããã
追è¨
- 11/12/26
- MLã®ã¹ã¬ããã¸ã®ãªã³ã¯ãééã£ã¦ããã®ã§ä¿®æ£ã
introduction
WebSocket ãªãããã¤ãã£ã¦ãå¾æ¥ã®ã¹ãã¼ãã¬ã¹ãªå¦ç以å¤ã«ãã³ãã¯ã·ã§ã³ãç¶ç¶ããã¹ãã¼ããã«ãªå¦çãå¯è½ã«ãªãã¾ããã
ãããå©ç¨ããã¨ãããã¾ã§å®è£
ãé£ããã£ããªã¢ã«ã¿ã¤ã ãªè¡¨ç¾ã Web ã«æã¡è¾¼ããã¨ãã§ãã¾ãã
ããã¦ã WebSocket ãç¨ããããã°ã©ã ãä½æããä¸ã§ãNode.js 㨠Socket.IO ãç¨ããæ¹æ³ã«ã¤ãã¦ã
ä»å¹´ã¯ãã®ããã°ã§ãä½åº¦ãç´¹ä»ãã¦ãã¾ããã
ä»æ¥ã¯ä»å¹´ä¸å¹´ã®é大æã¨ãã¦ãèªåãè²ã
試ããªããå¾ããªã¢ã«ã¿ã¤ã Web ã«é¢ããç¥èãæè¡ãªã©ãã
ããã«ã¾ã¨ãã¦ã¢ã¦ãããããããã¨æãã¾ãã
ä»åã話ãããã®ã¯ã 東京Node学園 3時限目 : ATND ã§çºè¡¨ããä¸è¨å 容ã®æç²ã§ãã
Node Academy | "About SlideStream & Tips for Realtime"
ãã®è³æã¯ãä»å¹´10æã«éå¬ãã 東京Node学園祭2011 ã®èªåã®ã»ãã·ã§ã³ã§ä½¿ã£ãã
SlideStream ã¨ããã¹ã©ã¤ããã¼ã«ã«é¢ããçºè¡¨ã§ä½¿ã£ããã®ã§ãã
ãã®çºè¡¨ã§ã¯ã
- SlideStream ã®ã¢ã¼ããã¯ãã£
- SlideStream éçºã®ä¸ã§å¾ãããçµé¨
ã«ã¤ãã¦è©±ãã¾ãããããã®è¨äºã§ã¯ãããå
ã«ãã¦ã主ã«ããªã¢ã«ã¿ã¤ã Webããããã«éçºãããï¼
ã«çµã£ã¦ã話ããã¾ããé·ãã§ãã
Caution
- ãããããSocket.IO åå¿è åãã¨ã³ããªã¯é£½ãããªãããããã®äººã対象ã«ãã¦ãã¾ãã
- ããªã¢ã«ã¿ã¤ã Web ã= ãWebSocket ãå¤ç¨ãã使ã£ã Webã ãããã®æå³ã§åã£ã¦ããã ãã¦ããã§ããã
- å®è£ ã« Socket.IO on Node.js ã使ã£ã¦ãããã¨ãæ¡ã«åæã«ãªã£ã¦ãã¾ã£ã¦ãã¾ãã
- çã® WebSocket ãå¥ã®è¨èªãã©ã¤ãã©ãªã使ãå ´åã¯ãå¿ ãããå ¨ã¦ãå½ã¦ã¯ã¾ãã¨ã¯éããªãã§ãã
- Socket.IO ã®ã»ãã¥ãªãã£ã¨ãããã¾ãåºã¦ãªã話ã«è§¦ãã¦ãã¾ããããã¯èªã¿æã«å®ç/å®å®³ãããããå¯è½æ§ãããããããã¾ããããä¸å責任ã¯åãã¾ããã
- èå¼±æ§ã¨ããè¨èã使ãã¾ãããç¥ãç¯å²ã§å®ä¾ã¯ããã¾ãããå¯è½æ§ã®è©±ããã¦ããã¨æã£ã¦ããã ããèªåã§æ¤è¨¼ãã¦ãã ããã
- SlideStream ã¯æ±äº¬Nodeå¦åç¥ã®åã«å²ã¨æ¥ãã§ä½ã£ãã®ã§ããã®å®è£ ããããã§ããå¤æããå®ç§ãªè§£ãã§ã¯çµ¶å¯¾ã«ããã¾ãããã話ã¯ãã®æã®å®è£ ããã¼ã¹ã§ãã
- ééã£ã¦ããå¯è½æ§ã¯å¤§ãã«æãã¾ããæ°ã¥ãããæãã¦ä¸ããã
SlideStream
åæã¨ãã¦ã SlideStream ã«ã¤ãã¦ãç°¡åã«ç´¹ä»ãããã¨æãã¾ãã
SlideStream ã¯
- Presenter ãã¹ã©ã¤ãã®ãã¼ã¸ãéãã¨ã Viewer ã®ãã¼ã¸ãä¸ç·ã«é²ãã
- Viewer ããã¼ã¸ãåããã¦ããä»ã®èª°ã«ãå½±é¿ããªãã
- Presenter ã®ãã·ã³ã®ã³ãã³ãã©ã¤ã³åºåãªã©ãããªã¢ã«ã¿ã¤ã ã« Viewer ã®ã¹ã©ã¤ãã«è¡¨ç¤ºãããã(ã©ã¤ãã³ã¼ãã£ã³ã°ãªãã¬ããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ã¨è¨ã£ã¦ã¾ã)
- HTML ãã¼ã¹ãªã®ã§ç»åãåç»ãªã©ã iframe, link ãªã©ã§åãè¾¼ã¿ãä»ã®ãªã½ã¼ã¹ãå ±æã§ããã
- ãã¼ã¹ã¯ deck.js ã
ã¨ãããã®ã§ãã
æ§æã¯ä»¥ä¸ã®ããã«ãªã£ã¦ãã¾ãã
Node-Ninja ã«ãããã¤ããããã»ã¹ã¯ä¸ã¤ã§ã Redis ãä¸é¨ä½¿ã£ã¦ã¾ãã
ä»ã«ç¹å¥ãªãã¨ã¯ãã¦ã¾ããã
ä»ã詳細ã¯ã¹ã©ã¤ããåç
§ãã¦ãã ããã
Auth(enticate|orize) of Socket.IO
ã¾ãã¯ãèªè¨¼(Authentication)ã¨èªå¯(Authorization)ã®éè¦æ§ã®è©±ã§ãã
ãã¼ã¸é·ç§»ã¨ Presenter ã®èå¥
æåã®æ©è½ã¨ãã¦ã Presenter (ã¤ã¾ãèªå) ãã¹ã©ã¤ãã®ãã¼ã¸ãéãã¨ã Viewer ã®ã¹ã©ã¤ãããã¼ã¸ã移ãã¾ãã
ããã¯ãèªåãã¹ã©ã¤ããåããæããã®ã¤ãã³ãã deck.js ã® API ããè£è¶³ããSocket ãµã¼ãã«éã£ã¦ããããã§ãã
Socket ãµã¼ã㯠broadcast ã§ããã®ãã¨ãå
¨ Viewer ã«ä¼ãã Viewer ã®ãã©ã¦ã¶ã¯ deck.js ã® API ãå©ãã¦ã¹ã©ã¤ãã®ãã¼ã¸ãå¤ãã¾ãã
ããã¯ãç¹ã«é£ãããä½ã¨ããªããã§ããã Presenter - Viewer ãä¸æ¹åã¨ãããã¨ãå¿ãã¦å®è£
ããã¨ã
æ¥ç¶ãã¦ãå
¨ã¦ã® Viewer ã®ãã¼ã«ã«ã§ã®ãã¼ã¸åãæ¿ãããå
¨ã¦å¥ã®ã¦ã¼ã¶ã« broadcast ããã¦ã
ããã¯ãã大å¤ãªãã¼ã¸åãæ¿ãã®åµã§ãå°ççµµå³å¿
è³ã§ãã
æ£ãã Presenter ã®ã¿ã®åãæ¿ããä¼ããããã«ããã«ã¯ã以ä¸ã®ããã«ãã¾ãã
- Socket ãµã¼ãã¯ãåã¯ã©ã¤ã¢ã³ãã®ã»ãã·ã§ã³ãèå¥ã§ããããã«ããã
- ãã®ä¸ã§ Presenter ã®èå¥ã ãã¯èªè¨¼ãã¦ãããããã®æ¥ç¶ã¯ Presenter ã ãã¨åããããã«ãã¦ãããã
- å ¨ã¦ã® Viewer 㨠Presenter ã¯ãã¼ã¸é·ç§»ã Socket ãµã¼ãã«éããã ãbroadcast ããã®ã¯ Presenter ã®ã¡ãã»ã¼ã¸ã ããã«ããã
ããã§å°ççµµå³ã¯é¿ãããã¾ããèªåã¯ãã¬ã¼ã³ãã¼ã·ã§ã³ã®åã«ã²ã£ããèªåã ãèªè¨¼ããã¦ãã¾ããã(認証ページ)
ããã¯åç´ãª HTTP ã¢ããªã® cookie ãã¼ã¹ã®ã»ãã·ã§ã³èªè¨¼ã¨åãã§ãã
WebSocket ã¯ãä¸æ¦ HTTP ã§ãªã¯ã¨ã¹ãããå¾ã upgrade ãçµã¦ WebSocket ã«ãããã³ã«ãåãæ¿ãã¦ããã
Socket.IO ã¯ãã®æã HTTP ãæã£ã¦ãæ
å ±ã WebSocket ã« handshakeData ã¨ãããªãã¸ã§ã¯ãã«ãã¦å¼ãç¶ãä»çµã¿ãæã£ã¦ãã¾ãã
ããã« Cookie ãå
¥ã£ã¦ããã®ã§ãããããã HTTP ã§ãèªè¨¼ããã¦ããã°ã WebSocket ã®ã³ãã¯ã·ã§ã³ããèªå¯ããã§ãã¾ãã
SlideStream ã§ã¯ä»¥ä¸ã®ããã«ãªã£ã¦ã¾ãã
ã¾ãã Express ã§èªè¨¼ãã»ãã·ã§ã³ãã¼ã¿ã« session.admin = true ã¨ãããã©ã°ãç«ã¦ã¦ããã¾ãã
WebSocket ã¸ã®åãæ¿ãæã¯ãããããã®ã¾ã¾ handshakeData ã«æ¸¡ãã¦ããã¾ãã
io.configure(function() { io.set('authorization', function(handshakeData, callback) { if (handshakeData.headers.cookie) { var cookie = handshakeData.headers.cookie; var sessionID = parseCookie(cookie)['connect.sid']; // check the express session store sessionStore.get(sessionID, function(err, session) { if (err) { // not found callback(err.message, false); } else { // found handshakeData.session = session; callback(null, true); } }); } else { return callback(null, true); // socket.io-client from node process dosen't has cookie // return callback('Cookie dosen\'t found', false); } }); });
ãã©ã¦ã¶ã§ãã¼ã¸ãåãæ¿ããã¨ã go ã¤ãã³ããçºçããã®ã§ã
ãããè£è¶³ããåã go ã¤ãã³ã㧠Socket ãµã¼ãã« Presenter, Viewer å
¨å¡ããã¼ã¸(to)ãéãã¾ãã
Socket ãµã¼ãã¯ã go ã¤ãã³ããåãåã£ãããã»ãã·ã§ã³ã®ãã©ã°ã確èªãã Presenter ã®ãã®ã ã£ãã¨ã(admin ãã©ã°ãæã£ãã¨ã) ã ããèªå以å¤ã« broadcast ãã¾ã(èªå¯)ã
socket.on('go', function(to) { if (!socket.handshake.session) return false; if (!socket.handshake.session.admin) return false; socket.broadcast.emit('go', to); });
ç´°ããå®è£
æ¹æ³ã¯ã以ä¸ã®äºã¤ãåç
§ãã¦ä¸ããã
- Socket.IO API 解説 - Block Rockin’ Codes ã®èªè¨¼ã®ã¨ããã
- Socket.IO と Express でセッションの共有 - Block Rockin’ Codes
Practice
Socket.IO ã«ã¤ãã¦ã¯ä¸è¿°ã®æ¹æ³ã§èªè¨¼ãã§ãã¾ããã¤ã¾ãåçã®ä»çµã¿ã§ WebSocket ã«ã¤ãã¦ãå¯è½ã§ãã
WebSocket ã¯éä¿¡ã®èªç±åº¦ãé«ã(Client/Server å
±ã« push ã§ãããã¯ãã¹ãã¡ã¤ã³ etc) ãªã®ã§ã
ãã®åã»ãã·ã§ã³/ã¤ãã³ããªã©ã®ç²åº¦ã§ãé©åãªèªè¨¼/èªå¯ããè¡ããã¨ã¯éè¦ã§ãã
ä¾ãã°ãä¸è¿°ã® ãPresenter ã«ãããã¼ã¸åãæ¿ããããã£ã¨éè¦ãªæä½ã ã£ãå ´åã©ãã§ãããï¼
ã»ãã·ã§ã³ãä¹ã£åãããã°ã broadcast 対象ã«ãããå
¨ã¦ã®ã¯ã©ã¤ã¢ã³ã(ããã§ã¯ Viewer)ã«ã
ä¸æ£ãªã¡ãã»ã¼ã¸ãéããã¨ãã§ãã¾ãã
ã¾ããå
·ä½çãªä¹ã£åãã¯ãä¸è¨æ¹æ³ã§ã¯ Cookie ã®ä¹ã£åãã¨ç価ã«ãªãã¨æãã¾ã(æªæ¤è¨¼)ã
ã¤ã¾ãã Cookie ã«å¤§ãã¦ã¯ããããããã¾ã§ã¨åçã«ãéè¦è¦ãã¦æ±ãå¿
è¦ãããã¨ãããã¨ã§ãã
(ãWebSocket ã§ã³ãã¯ã·ã§ã³ä¿æã ãããCookie ã¨ãããã©ãã§ãããããã§ã¯ãªãã¨ãããã¨ã)
ã¾ããå®è£
æ¹æ³ã«ãã£ã¦ã¯ã SessionStrage ã«ãããé¨åã®ãåç
§ãåçã«å¢ããå¯è½æ§ãããã¾ãã
ä»å㯠Redis ã使ã£ã¦ãã¾ãããååãªé度ãåºã¦ãããã Socket.IO / Express ã¨ã®ç¸æ§ã¯ããã¨æãã®ã§ããå§ããã¾ãã
broadcast injection
Socket.IO ã§ã¯ãã¤ãã³ãåã«ãæ°ãã¤ããæ¹ãè¯ãããã¨ãã話ã§ãã
WebSocket æ代ã®èå¼±æ§(ï¼)
å ¥éåããµã³ãã«ã ã¨ãä¾ãã°ä»¥ä¸ã®ãããªã¨ã³ã¼ãµã¼ãã®ä¾ãããã¨æãã¾ãã
// Server io.sockets.on('connection', function (socket) { socket.on('msg send', function (msg) { socket.emit('msg push', msg); socket.broadcast.emit('msg push', msg); }); });
// Client socket.on('connect', function() { $('#msg').click(function() { socket.emit('msg send', 'data'); }); socket.on('msg push', function (msg) { display(msg); }); });
ããã¯ããã©ã¦ã¶ä¸ã§æä½ãã¦ããã¨ã $('#msg') ã§ããä½ããã¯ãªãã¯ããªãã¨çºçããªãããã«ä½ã£ãã¤ããã ã¨å±ãªãã§ãã
ãªããªãããã®ç»é¢ã§éçºã³ã³ã½ã¼ã«ãªã©ãéãã°ã以ä¸ã®ããã«ããã¨ä»»æã®ã¡ãã»ã¼ã¸ã broadcast ã«è¼ãããã¨ãã§ãã¾ãã
socket.emit('msg send', 'æªæã®ããã¡ãã»ã¼ã¸');
Socket.IO ãã¾ãããããããªãã¦ããããããããã ããã¨æãç¨åº¦ããããã¾ãããã
æèããªãã¨ããããèå¼±æ§ã«ãªãå¯è½æ§ãããã¾ãã
ãã¡ãã Chat ã®ããã«ããã§ãè¯ãå ´åãããéããã¨ããã§ãªã«ï¼ãã¨ãããã¨ãããã¨æãã¾ãã
ã§ãããbroadcast 対象å
¨å¡ã«ä»»æã®ã¡ãã»ã¼ã¸ãéãããç¶æ
ã«ã¯ãæ°ãä»ããªãã¨ãããªãã¨æãã¾ãã
SlideStream ã®å ´å
SlideStream ã§ãã£ããã¡ãã£ã¨å ·ä½çãªä¾ãåºãã¾ãããã
SlideStream ã§ã¯ã Presenter (èªå)ããã¼ã«ã«ã® Emacs ã§å
¥åããæåãã
ãã¡ã¤ã«ããèªã¿åã Socket ãµã¼ãã«æ¸¡ãã broadcast ãã¦ãªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ãã¦ãã¾ããã
å
¥å㯠browser ã§ã¯ãªãã ãã¼ã«ã«ã«ç«ã¦ã Node ã®ããã»ã¹ããéã£ã¦ããã®ã§ã
å®é㯠Socket.IO(Socket ãµã¼ã) 㨠Socket.IO-Client(èªåã® Mac ) ã®éã§ã®ããã»ã¹ééä¿¡ã§ãã
ã¨ããããã®æå®ã¯ Socket.IO-Client ã®ãªã¯ã¨ã¹ã㯠Cookie ãæããªãã®ã§ãåè¿°ããèªè¨¼ãåºæ¥ã¾ããã§ããã
ããã¨åç´ã«ã¯ã以ä¸ã®ãããªã³ã¼ãã«ãªãã¾ãã(ä¾)
ã¾ãã codeStream ã¨ãã EventEmitter ããã Emacs ã«æ¸ããã³ã¼ããæµãã¦ãã¾ãã
ãããã code ã¨ããã¤ãã³ãåã§ã Socket ãµã¼ãã«éãã¾ãã
// Presenter Local Process var socket = require('socket.io-client').connect('http://' + host + ':' + port); socket.on('connect', function() { codeStream.on('code', function(data) { socket.emit('code', data); }); });
Socket ãµã¼ãã¯ã code ã¤ãã³ãã§å¾ããããã¼ã¿ãã Viewer ã« broadcast ãã¾ãã
// Socket Server socket.on('code', function(data) { socket.volatile.broadcast.emit('code', data); });
ãã©ã¦ã¶ã¯ code ã¤ãã³ãããçµæãåãåãã表示å¦çããã¾ãã
// Viewers Browser socket.on('code', function(data) { codeRender.rawRender(data); });
ãªãã¨ãªããããã§ããããï¼
ããã¦ãã®å ´åã Viewer ã¯ãã©ã¦ã¶ãã
socket.emit('code', 'm@(^_^) pugya~~~');
ã§ããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ãã¿ãã¨å°ç¡ãã«ãããã¨ãã§ãã¾ãã
èªè¨¼ãã§ããªããã©ãæ¾ã£ã¦ã¯ç½®ããªãã®ã§ã©ããããã¨ããã¨ã Socket ãµã¼ãã®ã¤ãã³ãã¯ã½ã¼ã¹ãè¦ãªãéãã¯ããããªã & çºè¡¨æã¯ã¾ã ã½ã¼ã¹ã¯å
¬éãã¦ããªã(ã¨ãããããããã£ã¦ããªãã£ã) ã®ã§ãã¤ãã³ãåã表ããã¯æ¨æ¸¬ãã«ããã ãããã®ã«å¤ãã¦ã対å¿ãã¾ããã
Practice
åå¿è åããµã³ãã«ã dis ãã¤ããã¯ããã¾ãã(ã¨ãããä¸ã®ã¯èªåã®è¨äºããã§ã)ããã ããã¡ããã¡ããã¨ãããªãæ°ãã¤ããã¹ãç¹ã¯ãããã«ã¯æ¸ããã¦ããªããã¨ãããã§ãããã
ãã¨ãv0.6? ãããã¾ã§ã¯ã Socket.IO 㯠'message' ã¨ããã¤ãã³ãåãã使ãã¾ããã§ããããä»ã¯ä»»æã®æååãæå®ã§ãã¾ãã
ã¾ããªã«ããããèªè¨¼ã§ãããªããã¦ãèªå¯ã«ãã£ã¦å¶éãããã¨ã大äºã§ãã
ããã§ããªããä¸è¨ã®ããã«ãªãããã®çç±ããèªè¨¼/èªå¯ã§ã®å¶éãé£ããã¨ãã
ãã¨ã Cookie ãçã¾ãã¦ããã®ã¤ãã³ãã ãã¯ä»»æã«å©ãããã¨ã¾ããã
ã¨ãããããªãã®ã¯ãæ¨æ¸¬ãã«ããã¤ãã³ãåã«å¤ãã¾ãããã
ã¤ãã³ãåã¯ãéãå´ã¨åããå´ã ãåãã§ããã°è¯ãã§ãã
ä¸ã®ä¾ã®ããã«ããããåãã«ããã¨ãããå
¨ã¦åãã«ããããç°¡åã«æ¨æ¸¬ã§ãã¾ãã
ããªãã®ä½ã£ã MMO ã²ã¼ã ã¯ã socket.emit() ã ãã§ç»é¢ã®ç«¯ã¾ã§ã¯ã¼ãã§ããããã¾ãããï¼
ãã ã§ãããã¯ã©ã¤ã¢ã³ããèªç±ã«ã¯ãã¹ãã¡ã¤ã³ããæ¥ç¶ã§ãã¦ã emit() ã ãã§æ軽ã«ãã¼ã¿ãéãã¤ãããã¦ãã¾ãã®ã§ã
éè¦ãª API ã¯ã©ã³ãã æååãªã©ãç¨ããæ¹ãè¯ãå ´åãæãããããã¾ããã
ãã¡ããã½ã¼ã¹ãå ¬éãã¦ãã¾ãã¨å ãåããªãã®ã§ãDB ã®ãã¹ã¯ã¼ãã¨ãã¨åãããã«ãå¥ãã¡ã¤ã«ã«åºã㦠.gitignore ãªã©ã®é è½å·¥ä½ãå ´åã«ãã£ã¦ã¯å¿ è¦ã§ããã¤ãã³ãåã¯åãªãæååãªã®ã§ããããã¯ãããã§ãããã¾ãã
ä»å¾ã¯ããã®ã¤ãã³ãåããã¾ãé è½ããä»çµã¿ãæããè²ã
åºã¦ããã§ãããã
ãã¬ã¼ã ã¯ã¼ã¯ã¬ãã«ã§ã®è§£æ±ºã¯æããªã±ã¼ã¹ã ã¨æãã¾ããã
èªåãå¾ã§è¿°ã¹ãèªä½ã®ãã¬ã¼ã ã¯ã¼ã¯å
ã§ã¯ãã®åé¡ãæ±ãããã¨æã£ã¦ãã¾ãã
volatile & diff
話ã¯å¤ãã£ã¦ããã©ã¼ãã³ã¹ç³»ã®è©±ã§ãã
ä¾ãã°ããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ã§ãæ¸ããã½ã¼ã¹ã³ã¼ãæååã broadcast ããã¨ãªãã¨ãã¡ãã£ã¨å¤§ããªã½ã¼ã¹ã«ãªã£ãæ
ãDiff ãéã£ã¦ããã©ã¦ã¶ã§å¾©å
ããã°å¹çãããã®ã§ã¯ï¼ãã¨ããèããæµ®ãã³ã¾ãã
JS ã«ã¯ google-diff-match-patch ã¨ãããã®ãã®ãºããªãªã©ã¤ãã©ãªãããããã
å®éèªåããããèãããã§ãããããã¯ããã¦ããä¸æåå
¥åããæ¯ã«ãã½ã¼ã¹å
¨ä½ãéãããé¸ã³ã¾ããã
æ¡ç¨ã¯ããªãã£ããã©ãå®è£
ã¯ããã®ã§ããã®æ®éª¸ãå®ã¯ http://d.hatena.ne.jp/Jxck/20111112/1321079097 ã ã£ãããã¾ãã
Both-sides Javascript èªä½ã¯ä¾¿å©ãªã®ã§ãã£ã¡ã§åºãã¾ããã
ãããå¤æã¯ã Socket.IO ã® ãVolatile ã®æ§è³ªãã¨ãå¾è¿°ãããCPU 㨠I/O ã®ãã©ã³ã¹ãããæ¥ãç©ã§ãã
volatile ãªãã·ã§ã³
volatile ãªãã·ã§ã³ã«ã¤ãã¦ã¯ãここã®ãæ®çºæ§ã¡ãã»ã¼ã¸ããèªãã§ä¸ããã
ç°¡åã«è¨ãã° TCP 㨠UDP ã®é¢ä¿ã§ããéé確èªã®æç¡ã§ããã¡ãªã¿ã«éé確èª(ACK) ã«ã¤ãã¦ãåãè¨äºã«æ¸ãã¦ããã®ã§ãåããã¦èªãã§ããã¦ä¸ããã
ãã¦ã volatile ãªãã·ã§ã³ãä»ã㦠diff ãéãã¨ã diff ã®ééãæ¬ æããå ´åããããã«å¾©å
ã§ããªãå ´åãããã¾ãã
ä¾ãã°ã ãfoo ãæ¸ããfoo ãæ¶ãã¦ã bar ã«ãããã¨ããå¦çãã 3 ã¤ã® diff ã«ãªã£ãã¨ãã¾ãã
+ foo
- foo
+ bar
æå¾ ããçµæã¯ãã¡ãã
bar
ã§ããã volatile ãã¤ãã¦ããã¨ãã¦ãçãä¸ã® -foo ãæ¬ æãããã以ä¸ã®çµæã«ãªãã¾ãã
foo bar
ãã¡ããã volatile ãä»ããªããã°ãæãããªãã©ã¤ãã¦æ£å¸¸ã«ããã¨æãã¾ãã
ãããªãã¦ããéé(ACK)ã確èªãã¨ã©ã¼ãæ¤ç¥ãã¦å
¨é¨åãç´ãã¨ãããããã¯ããã¾ãã
volatile æç¡ã®å¤æ
ããã¤ãã®è¦å ãã volatile ã使ãæ¹åã§å®è£ ãããã¨ã«ãã¾ããã
ã¾ãããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ã¯ãã¼ã¸åãæ¿ããªãããããã£ã½ã©ãªã¢ã«ã¿ã¤ã æ§ãé«ãã
SlideStream ã§ã¯1æå1ã¤ãã³ãã§è¨è¨ãã¦ãã¾ãã
ãã®å ´åãã©ããã§è©°ã¾ãã¨ãã³ã¼ãã£ã³ã°ã®è¡¨ç¤ºãæ¢ã¾ãå¯è½æ§ãããã¾ãã
ã¤ã¾ã volatile ãä»ããªãã¨è©°ã¾ã£ãå ´åã®å¶å¾¡ãèããå¿
è¦ãã§ã¾ãã
éã« volatile ãä»ãã¦ããã¤æ¯åå
¨æéã£ã¦ãã¾ãã°ãä¸æåæ¬ æãã¦ãã
ãã®æ¬¡ã®ã¤ãã³ãã§å
¨é¨ã®ã³ã¼ããæ¥ã¦ãå
¨é¨æ¸ãç´ãã°ã Viewers ã«ã¯2æåã®è¡¨ç¤ºãéãã£ãããã«è¦ããã ãã§ãã
ã¾ããå½æ¥ãä¼å ´ã®ãããã¯ã¼ã¯ãã©ã®ç¨åº¦ã®ãã®ãªã®ããæ³å®ã§ããªãã£ãã®ãããã¾ãã
ãªã«ãããããå
¨é¨éã£ã¦ã丸ã£ã¨æ¸ãç´ããã¹ã¿ã¤ã«ã¯ãå®è£
ãã¨ã¦ã楽ã ã£ããã¨ãããã¾ãã
Practice
ä»ã¯ããªã¢ã«ã¿ã¤ã ã¨ä¸è¨ã§èªããã¦ãã¾ããããªã¢ã«ã¿ã¤ã ã«ãç¨åº¦ãããã¾ãã
ä¸åã«ä¸åã®ãã¼ã¸åãæ¿ãã¨ãä¸æåä¸åã®ã³ã¼ãã£ã³ã°ã§ã¯ãã¤ãã³ãã®é »åº¦ãéãã¾ãã
å¾è
ã®å ´åãä¾ãã°ã²ã¼ã ã§ã®åº§æ¨ç§»åãããã¦ã¹ã«ã¼ã½ã«ã®åãã Twitter ã®ã¹ããªã¼ã ãªã©ãæ±ãå ´åã
ããããå¤å°æ¶ãã¦ãããããã®ã§ããã°ã volatile ã使ããã¨ã Socket.IO ã®ããã¥ã¡ã³ãã§ãæ¨å¥¨ããã¦ãã¾ãã
volatile ãã¤ããªããã°ãééã®ç¢ºèªãã§ãã¾ãããä¸ã®ä¾ã§ã¯ããã¯é©åã§ã¯ãªãã§ãããã
ã¾ããå®è£
ãèªãã¨ã volatile 㯠socket ã«æ¸ãè¾¼ããªãã£ããæ¨ã¦ãã¨ããå®è£
ã®ããã§ãã
(ã¤ããªãã¨ããã®æ ACK ã®ã³ã¼ã«ããã¯ãå®è¡ãã¦ããªãã©ã¤/ã¿ã¤ã ã¢ã¦ããªã©)
ãããã©ã®ç¨åº¦ã®é »åº¦ã§ããããã¯ãå½æ¥ã®ãããã¯ã¼ã¯ã¨ã¯ã©ã¤ã¢ã³ã PC ã®ç¶æ
ã«ä¾åããã¨èãããã¾ãã
ã¤ã¾ãããã®æ§è³ªä¸ãäºåå¤æã¯ããããããç¾å®çã« ããã®æ Socket ã«æ¸ãè¾¼ãããã©ããï¼ããã
å¤æåºæºã«ããã®ã¯é£ããã ãããã¨ãä»ãå ãã¦ããã¾ãã
Domain Specific implementation
ããã¯ãè³å¦ããããåé¡ããããã¾ããããçç´ã«ãã£ããã¨ãæã£ããã¨ãæ¸ãã¾ãã
ä»ã¾ã§ã®ã©ã¤ãã©ãªãç¹ã«ãæ±ç¨æ§ãããã£ããã®ã¯ããªã¢ã«ã¿ã¤ã ã«ä¸åããªå¯è½æ§ãããã¨ãããã¨ã
è¬ã®ããã«ããã¯
é·ãã®ã§ç°¡åã«è©±ãã¨ã SlideStream ãæ¬çªåã«ä½äººãã«æ¥ç¶ãã¦ããã£ã¦è©¦ããããã ãã ããã®åãéãããªã£ã¦ãã¾ãã使ãç©ã«ãªãã¾ããã§ããã
åå ãæ¢ãããã«ã node ã®ãã°ããããã»ã¹ãªãããè²ã
調ã¹ã¦ããç¹ã«åé¡ã¯ãªãã
ãã¼ã«ã«ã§è©¦ãåã«ã¯åºãªãã£ãã®ã«ãæ¬çªæ°æ¥åã«æ°ã¥ããã®ã§ãã¨ã¦ãç¦ãã¾ããã
çµè«ããè¨ãã¨ãéããã£ãã®ã¯ãã©ã¦ã¶ã®èªæ»
ã§ããµã¼ãããããã¯ã¼ã¯ãå
¨ãé¢ä¿ãªãã£ãã®ã§ãã
ã·ã³ã¿ãã¯ã¹ãã¤ã©ã¤ãã¨å¾æ¥ã®ã©ã¤ãã©ãª
æ¥ããããã§ããããã£ãã¾ã¾è©±ãã¨ãåå ã¯æå¤ã«ããã·ã³ã¿ãã¯ã¹ãã¤ã©ã¤ãã§ããã
ä»åãã³ã¼ãã®ã·ã³ã¿ãã¯ã¹ãã¤ã©ã¤ãã¯ã使ãæ
£ãã SHJS - Syntax Highlighting in JavaScript ã使ã£ã¦ã Bash 㨠Javascript ãè²ä»ããã¦ã¾ããã
ãã®ã©ã¤ãã©ãªã¯ã pre ã¿ã°ã®ä¸ã®æååãä¸æ°ã«æ¸ãæããã®ã§ãvolatile ãé¸ãã ä»åã®å ´åãã³ã¼ããæ¯åå
¨é¨éããã¦ãã¦ããããæ¯åããã£ã¨ãã¤ã©ã¤ããã«ãªãã¾ãã
ã§ãããããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ä¸ãã®åãåæ°ç¹°ãè¿ãã¦ããã¨ããã©ã¦ã¶ã§ã¡ã¢ãªããã®åãæ¶è²»ãããã¹ã©ã¤ãããã®åãé
ããªã£ã¦ãã¾ããã
Node.js ã§ãªã¢ã«ã¿ã¤ã ã¨ãããã¨ã§ãããã«ãã¼ã¿ã®è»¢ééãã Node ããã»ã¹ãçã£ã¦ãã¾ã£ãã®ã§ãããChrome ã®ã³ã³ã½ã¼ã«ãéãã°ä¸çºã§ããããã¨ã§ããã
ã·ã³ã¿ãã¯ã¹ãã¤ã©ã¤ããã¡ã¢ãªãªã¼ã¯ãã¦ããã®ãã調ã¹ã¦ãç´ãã¦ãè¯ãã£ããã§ãããèªåã«ã¯ã¨ã«ããæéãããã¾ããã§ããã
ãããã SHJS ãä»è¨èªã®ãã¤ã©ã¤ãã«å¯¾å¿ããããã«ããªãã¸ã§ã¯ãæåã®æµåã§ã¯ã©ã¹ãåå²ããæ¡å¼µæ§ãæ±ç¨æ§ãé«ãã¦ãããã¨ã«ããã
çæããããªãã¸ã§ã¯ãã«ç¡é§ããããã¨ã¯æç½ã§ããã
ä»åã®çºè¡¨ã¯ã¹ãã¼ãªã¼ãæ¦ã決ã¾ã£ã¦ã¦ããã¤ã©ã¤ããããã½ã¼ã¹ãåãã£ã¦ãã¾ãã
ã¾ããå®ã¯ãã¤ã©ã¤ãã£ã¦ãããã£ã½ãè²ãã¤ãã¦ãã¨ãããã£ã½ãè¦ãããã®ã§ã(æ¨æºãç¡ãã§ãã)ã
ããã§ã以ä¸ã®ããã«æ¥ãã§ä½ã£ãæ£è¦è¡¨ç¾ã§ãSHJS ã® css ã ãåãã¦ãã ããã SHJS ã¨åãããã«ãã¤ã©ã¤ããããã®ã以ä¸ã®ããã«æ¸ãã¾ããã
è¦ãã¨å²ç¬ããã¦ãã¾ããããªãæ¥ããããã³ã¼ãã§ãããããã¦å¼µãã¾ãã
render.prototype.higlightJS = function() { this.cache = this.cache .replace(//g, '>') .replace(/"(.*?)"/g, '\"$1\"') .replace(/'(.*?)'/g, '\'$1\'') .replace(/(var|function|static|true|false)/g, '$1') .replace(/([A-Za-z0-9]*?)\(/g, '$1(') .replace(/^\/\/(.*)/g, '//$1') .replace(/[^:]\/\/(.*)/g, '//$1') .replace(/\/\*\*(.*)/g, '/**$1') .replace(/\*(.*)/g, '* $1') .replace(/(\d{2,4}?)/g, '$1') ; }; render.prototype.higlightBash = function() { this.cache = this.cache .replace(/(ls|cd|tree|rm|\sexpress\s|npm|\snode\s)/g, '$1') .replace(/(create)/g, '$1') .replace(/(Jxck\$)/g, '$1') .replace(/(\d{4}?)/g, '$1') ; };
æãã¤ããé ã« replace ãã¤ãªããã ãã®ã³ã¼ããªã®ã§ãä¸èº«ã¯ããåããã¨æãã¾ãã
ããããããã«ç½®ãæãããã¨ã§ã SlideStream ã¯ãã®ãªã¢ã«ã¿ã¤ã æãå¾ããã¨ãã§ãã¾ããã
Practice
SHJS ã¯ãã¡ããæªãæãã¾ããããã ãããã¯ã SHJS ã
ããã©ã¦ã¶ã®æåã®è¡¨ç¤ºã§ä¸åã ãåä½ããããã¨ãæ³å®ãã¦ããã
ã¤ã¾ãå¾æ¥ã® Web ã§ã®ç¯å²ã«æé©åããããã®ã ã¨ããã ãã®è©±ã§ã
ãã®ç¯å²ã§ã¯ãè¨èªã®å®ç¾©ã追å ãããã¨ãç°¡åãªãæ¡å¼µæ§ã®ãããã°ãããã©ã¤ãã©ãªã§ãã
ããããããããæ¢åã®ã©ã¤ãã©ãªãããªã¢ã«ã¿ã¤ã ãªå ´é¢ã§ã¯é©ããªãä½ãã«ãªã£ã¦ããå ´åãããã
ã¨ããå¯è½æ§ãçæããå ´é¢ã§ããã
ãã¡ãã SHJS ã®æ¡å¼µæ§ããã®ã¾ã¾ã«ããªã¢ã«ã¿ã¤ã ã«æã£ãå½¢ã«æ¹åãããã¨ãåºæ¥ãã§ãããã
ã§ããããã§ã¯ããã¨ã¯å¥ã«ããä¸ã¤ããã®æ¡å¼µæ§ãæ¨ã¦ãã°ãã£ã¨éããªãããï¼ã¨ãã解ãåºã¦ããã¨æãã¾ãã
ã¡ãã£ã¨é£èºãã¾ãããä¸æãè¨ããªãã§ããã
ãå¾æ¥ã® Web ããç¾ç¶ã®å ¨ã¦ã®ä»æ§ãæºãããã¾ã¾ãªã¢ã«ã¿ã¤ã ã«ããã
ã¨ãããããªè¦ä»¶ããä»å¾åºãããããã¾ããã
ãã®è¨äºã«ä¸ãã£ã¦ããã¨ãä¸ãã£ã¦ãªãä»ã®è¦å å«ãã¦ãèªåã¯é£ããã¨æãã¾ãã
ããã§ã¯ãä½ããæ¨ã¦ããã¨ããããããã£ã¨ç©æ¥µçã«ãå¿
è¦æå°éã«ããããéè¦ã«ãªãå ´é¢ãããæ°ããã¦ã¾ãã
ä»åã¯ã¾ã è¯ãã¨ãã¦ãããªã¢ã«ã¿ã¤ã ã²ã¼ã ãããã®ä¸çã«ãªãã°ã
@tkihira: ä»æ¥ã®ããã°ï¼ URL ï¼ã«ãæ¸ãã¾ããããæ±äº¬?ãã¥ã¼ã¨ã¼ã¯ã®è·é¢ã10860kmãå ã®é度30ä¸kmã ã¨ãå¾å¾©ã«0.072ç§ããã£ã¦ãã¾ãã¾ããæ ¼éã²ã¼ã ã®ãã¬ã¼ã æ°ã§ããã°4.34ãã¬ã¼ã ãè´å½çãªã©ã°ã§ããå ã®é度ã¯é ãããï¼
ã¨ãå ã®éããåé¡ã«ä¸ãããããããéãããéè¦ã«ãªãã¾ãã
ä¾ãã°ãä»åã®å ´åãã使ãè¨èªãã使ããã¼ã¯ã¼ãããåãã£ã¦ã¾ããããã以ä¸ã«å¯¾å¿ãã¦ããé
ããªãã ãã§ããã
ã ã¨ããããç¾åãã訳ã§ã¯ããã¾ããããèªåãæ¸ãã replace ãã§ã¤ã³ã¯ãããªãã¡æªãæ¹æ³ã§ã¯ç¡ãã£ãã¨ãããã¨ããã§ããªãç¡ãã®ã§ã¯ãªãã§ããããï¼
(ãã£ã¨éãã§ããã¨ãã¯å¥ã¨ãã¦ã)
é«éåãããã¯ä»ã¾ã§ããã£ã話ã§ããã§ã High Performance Web Sites ãªããã«è¼ã£ã¦ããã®ã¯ã
ãã©ã¦ã¶ã®èªã¿è¾¼ã¿ãµã¤ãºãæ¸ããã¨ããæåã®è¡¨ç¤ºãããã«éããããã¨ãã確ããããã話ã§ããã
ãããããªã¢ã«ã¿ã¤ã ãªå ´åãæåã®è¡¨ç¤ºã大äºã§ããã表示ãã¦ãããåè² ã§ãã
ã¨ã«ãããªã¢ã«ã¿ã¤ã ã«è¦ãããå ´é¢ãããªã¢ã«ã¿ã¤ã ã«è¦ãããã¨ãéè¦ã ã¨æãã¾ãã
ãã®ããã«ã¯ãå
ã®éãã¾ã§æ°ã使ã£ã¦ãæ¥ããããæãã®ã³ã¼ãã«ãªã£ã¦ã§ãæå°éã®å®è£
ã®æ¹ãããããããã¾ããã
èªåã¯ãããè¸ã¾ãã¦ãçºè¡¨ã®ã¨ãã¯ãã®ãããªè©±ããã¾ããã
important for realtime is looks like realtime
ã¡ãã£ã¨éæããªæãªæ°ããã¾ããããããããã¨ã§ãã
ãããã« replace ãã§ã¤ã³ã¯ãåã«æ±ç¨æ§ã失ã£ã¦ã¦ãããèªä½ã¯è¦æ¨¡ã®å¤§ããéçºã®å ´é¢ã§ã¯ãæªãã§ããã§ãããã
ããããããã®ãããå²ãåã£ãå®è£
ããéããéè¦ããã«ã¯å¿
è¦ããããããã«ã¯æã£ã¦ããã¹ãã ã¨èªåã¯æãã¾ããã
ã¹ãã¼ãçãªæ¹ã
ããååã«ç価ãçºæ®ããå ´é¢ã¨è¨ããããããã¾ããã
balance btw CPU Heavy & I/O Heavy
ããã¯ããªã¢ã«ã¿ã¤ã ã«éããã Node.js ã使ãä¸ã§ç解ãã¦ããã¹ãç¹ã§ãã
ããããNon-Blocking I/O ãã¤ãã³ãã«ã¼ãã®è©±ã¯ç解ã§ãã¦ãåæã§æ¸ãã¾ãã
ãã¸ãã¯ã¨ã¤ãã³ãã«ã¼ã
ãã®è©±ã¯ãå
·ä½ä¾ã¨ãã¦å
ã»ã©ã® Diff ã®ä»¶ãã¨ã£ã¦èª¬æãã¾ãã
ãã£ãã®è©±ãèªãã§ã
ãèªåãªã volatile ãã¤ãã¦ãããã¨ã復å ãå«ã㦠diff ã§ã°ã£ã¡ããã¸ãã¯ãå®è£ ã§ãããï¼ã
ã¨æã£ãæ¹ãããã¯ãã°ãããã§ãããããªããçµããã¸ãã¯ã¯ãã¤ãã³ãã«ã¼ããæ¢ãã¾ãããï¼
Node.js ãã·ã³ã°ã«ããã»ã¹ã§åããã¦ã nextTick ãªã©ã®ãã¯ããã¯ã使ããã«ãå®ç´ã«è¤éãªãã¸ãã¯ãçµãã å ´åã
ãã®ãã¸ãã¯ã CPU ãå æãã¦ããéããã¤ãã³ãã«ã¼ããæ¢ã¾ããç¶æ
ã«ãªãå¯è½æ§ãããã¾ãã
ã¤ã¾ãããããããã«ããã¯ã¨ãã¦ãä»ã®å¦çããããã¯ããã¾ãã
ããã Node.js 㧠CPU Heavy(= CPU ããããã使ãå¦ç)ãæ¸ããªãããã«æ°ãã¤ããã¹ãçç±ã§ãã
対ãã¦ã I/O Heavy(= Disk, NW ã¸ã®èªã¿æ¸ããããã¤ãã¤è¡ãå¦ç) ã«ã¤ãã¦ã¯ããããã©ããªã«éããã¦ããããã¯ãã¾ããã
ã ããã SlideStream ã®ããã«ãã£ã1ããã»ã¹ã§åãã¦ããã¹ã©ã¤ããã¼ã«ã«ã2-300ã¢ã¯ã»ã¹ããã£ã¦ã broadcast ãç¹°ãè¿ãã¦ãã¡ããã¨åãã¾ãã
ä¸æ¹èªåã® Mac ã¯ä¸æåå
¥åããæ¯ã« Disk, NW ã«ã¢ã¯ã»ã¹ãã¦ãããã¡ã³ãããªã声ãä¸ãã¦æ¥ãæ¸ããã¨ãããã¾ããã
1ããã»ã¹ã®1ã¹ã¬ãããªã®ã§ã¡ã¢ãªã使ããªãããC10K åé¡ãããã¾ããã(ããã¯ãã¡ãã£ã¨ãããã³ããã¼ã¯ãæå¾ã«è¼ãã¾ãã)
ããã Node.js ã®ã¡ãªããã§ããããªã¢ã«ã¿ã¤ã ã¨ç¸æ§ãããã¨ããçç±ã®ä¸ã¤ã§ãã
ãã®ã¡ãªããã¯ã「ブロックしちゃうような処理とか書かないし!!」ã¨é¡ãçã£èµ¤ã«ãã¦è¨ã人ããããããçç±ã®ä¸ã¤ã§ãã
Event-loop harassment Pan-da
ãã¦ããããã¦ããããã¯ãã¡ãããããªå¦çããæ¸ãã¦ãã¤ãã³ãã«ã¼ããæ¢ãã¦ãã¾ããã¨ãã
å
Joyent ã®ãã¼ãã¨ãã³ã¸ã§ãªã¹ãã§ãä»ã¯ Node.js ã®ããã©ã¼ãã³ã¹ã®ã³ã³ãµã«ã¿ã³ãããã£ã¦ããã @sh1mmer ã¯ãã表ç¾ãã¾ããã
ãã¤ãã³ãã«ã¼ããã©ã¹ã¡ã³ããã³ããã§ãã(å ãã¿ã¯ JSConf2011 のこの資料 P29)
å ãã¿ã¯ãµã¦ã¹ãã¼ã¯ã®ãã»ã¯ã·ã£ã«ãã©ã¹ã¡ã³ããã³ããã¨ããæ¥æ¬ã§ã¯ãããéããªããã¿ã§ãã
Diff ã«è©±ãæ»ãã¾ãããã
Diff åãå¦çã¨ããããæ»ãå¦ç㯠CPU æ¼ç®ã§ãã
ãããã volatile ãä»ããã«å®ç¾ãã¦ããªã«ããªã®ãã¸ãã¯ã追å ãã¦ãã£ãã¨ããã¨ã
ããããã©ãã©ã CPU Heavy ã«ãªãå¯è½æ§ãããã¾ãã
ä¸æ¹ãå
¨é¨ã¾ãã£ã¨éãããåç´åããå¦çã¯ãã»ã¨ãã©ã I/O ã§ã®åã渡ãã§ãã
ããã¦ããã®ãåç´ã«ããã¨ããæé©åãã¯ãã¤ãã³ãã«ã¼ããæ»ããã«åãã
ãããªã¢ã«ã¿ã¤ã æ§ãå¢ãå ´åãããã¨è¨ãã¾ãã
ã¤ã¾ã Node.js ã¯ã
ãä¸æã«æé©åãããã¨ããããæ¼ç®ãã¸ãã¯ãæ¸ãã»ã©ã«ãã¤ãã³ãã«ã¼ããæ¢ãã¦é ããªãå¯è½æ§ãããã
ã¨ãããã¨ã§ãã
ããã¯ãå®ã¯ãã©ã¦ã¶ã§ãåãã§ããWebWorker ã setTimeout ãªã©ã使ãæãããã¾ãããããããã©ã³ã¹ã§ãã
ãããè¸ã¾ããã¨ãå
ã»ã©ã®ãã¤ã©ã¤ãã®replace() ããã¤ãã³ãã«ã¼ãã®åæ¢ãæå°éã«æãã¦ããã¨ããè©ä¾¡ãå¯è½ã«ãªã£ã¦ãã¾ãã
simple is fast, fast is realtime
çºè¡¨ã§ã¯ããããªãµãã«ã¾ã¨ãã¡ãã£ããã©ããã®æã¯ãããããã¨ã話ãã¦ãã¾ããã
馬鹿ã¿ããã«åç´ãªå¦çã®æ¹ãéãå ´åãæãã¾ãã
ã¨ãããããããã馬鹿ã¿ããã«åç´ãªå¦çãã§ã¯ãªãã
ãCPU Heavy ãªã®ã? I/O Heavy ãªã®ãï¼ã
ã¨ãã観ç¹ã§è¦ãå¿ è¦ãæãã¾ãã
ç¹ã«ããµã¼ãã¯å¦çãéä¸ããã®ã§ããã¸ãã¯ã«ãã£ã¦ã¯ãããã¯é¡èã«åºãå ´åãæãã¾ãã
ãã¨ãã°æè¿ãNodejs_jp ã® ML にあがったこれãªãããã®å
¸åã¨è¨ããã§ãããã
ãã¡ãããå
¨ã¦ã I/O ã§ã«ãã¼ããã«ãéçãããã®ãäºå®ãªã®ã§ã
éè¦ãªã®ã¯ãã©ã³ã¹ã§ãã
ãµã¼ãã¯ã¯ã©ã¹ã¿ãçµããã¨ãåºæ¥ã¾ããå°æ¥çã«ã¹ã¬ããã®ãããªä»çµã¿ãå
¥ãäºå®ã§ãã
ã§ããæ¬æ¥ã® Node.js ã®æ§è³ªãç¥ããã¨ã®æ¹ãå
ã ã¨æãã¾ãã
ããããã°ã ãã£ãããããé
ãçç±ãåããã¨æããã
èªåã Jxck's OutPut - Nodeにテンプレートエンジンはもういいかな ã¨èããçç±ãä¼ããããããã¾ããã
çºå±ããã㨠シングルページっぽいアプローチ(SSP) ããããããªãã¨ãã
ãã®ã¡ãªãããçãããªãã¢ããªã¯ã Rails ã¨ãã§ããã°è¯ãã®ã§ã¯ï¼ã¨ããããããè«ããã¡ãã¨ã§ãã¾ãã
ãããããã©ã³ã¹ã£ã¦ã©ãã§è¦ãã®ãï¼ããã¯é£ãã§ããã次ã«ããä¸ã¤è©±ããããä¸ã¤ã®ã¢ããã¼ããç´¹ä»ãã¾ãã
Client <> Server
SlideStream ã®å ´åãã¡ã¤ã³ã®ã¯ã©ã¤ã¢ã³ãã¯ãã©ã¦ã¶ã§ãã
ããã¦ãã©ã¦ã¶ã®æ§è½ããPC ã®ã¹ããã¯ããã©ãã©ãè¯ããªã£ã¦ãã¾ãã
ãã®ä¸ã HTML5 ã§åºæ¥ããã¨ãå¢ããNode.js ã®ç¹æ§ã§ãããã
ãã¯ã©ã¤ã¢ã³ãã¨ãµã¼ãã§åãè¨èªã使ããï¼Both-Sides JavaScriptãã®å©ãããã£ã¦ã
é¸æè¢ã¯åºããã¾ããã
ããã®å¦çã¯ãã¯ã©ã¤ã¢ã³ãã¨ãµã¼ãã©ã¡ãã«ãããããï¼ã
ã¯ååã«èãã¦ããå¾æ¥ã®ãµã¼ããå
¨é¨ãã£ã¦ãã©ã¦ã¶ã¯è¡¨ç¤ºã ããã¯å¹¼ç¨åã¾ã§ãªã®ã¯ãã¡ããã
ãAjax ã§ãã¼ã¿ãéåæã« Pull ãã¦è¡¨ç¤ºããå°å¦çã¾ã§ãªã®ã¯è¨ãã¾ã§ãããã¾ããã
ãã¸ãã¯ããã£ã¡ãæãããå ´åã«ãã£ã¦ã¯ã¯ã©ã¤ã¢ã³ãã ãã§å®çµããæ代ã§ãããã
Practice
ããããã©ã³ã¹ã§ããããã¾ã§ã®è©±ãç·æ¬ããã¨ã Node.js ãã¼ã¹ã®ã¢ããªã«ã¯ã
ãã®ãã©ã³ã¹ãåã軸ã¨ãã¦å¤§ããåã¤ã®é¸æè¢ããããã¨ããããã¾ãã
ä»å SlideStream ã§è¨ãã°ãéãå°ããããçã£ããã¨ã«ãªãã¾ãã
ãªãã¹ã I/O ã«å¯ãã¦ãã¾ãã主㫠Socket.IO ã® broadcast ãµã¼ãã§ãã
ã¾ãããµã¼ãã§ãã¤ã©ã¤ããã¦ãããã¯ã©ã¤ã¢ã³ãã«éãã¨ããå¦çãã§ãã¾ããã
ä¾ãåç´ãª replace ã§ããµã¼ãã§ã¯ããã¾ãããã¯ã©ã¤ã¢ã³ãã«ãããã¾ãã
ãã®è¡¨ã§ããµã¼ããªã³ãªã¼ã§CPUæ¼ç®ãããã(赤ãå°)ã£ã¦ã©ãã§ãããï¼
ãã¶ãããããè¦ä»¶ãªãã ãRails ã§ããã®ã§ã¯ï¼ãã¨ããæå³ãä¼ããã§ããããï¼
ã¾ããã¨ã¯æãã¾ããã Rails ã dis ãæ°ã¯ãããããªãã§ããã¨ããã Django ã§ã Cake PHP ã§ãããã§ãã
ããããã¡ãªãã/ãã¡ãªãããã¡ããã¨ç解ãã使ãåããã¡ããã¨ããã°ããã ãã§ãã
ããããã°ã誰ããé¡ã赤ãããããã¦æ®å¿µãªãã¨ã«ãªããã¨ãããã¾ãããããããã®è¦ãã®ã¯ãã¾ã好ãã§ã¯ãªããã§ãã
(è足ã§ãããä¸é¨ããªã¢ã«ã¿ã¤ã 㪠Web ã®æ§æã¨ãã¦ããNode+Railsã§é£æºãã¦ä¸¡æ¹ã®ããã¨ããåããã¨ããã®ã¯ããã ã¨æã£ã¦ãã¾ãã)
ãã®è¾ºã®èãããããã¨ããã¨ã¯ã¢ããªæ¯ã«æé©åããã ãã§ãã
ã¡ãªã¿ã«åºãã¦ããã¦è¨ãã®ããªãã§ããããã®ãããªã¯ã¹ã«ãã¨ããããªãæ¹ãããã§ããä¾ã§ãã
ãã³ããã¼ã¯
SlideStream ã«ã¤ãã¦ã¯ããã®ã¹ã©ã¤ãã https://node-ninja.com/ ã«ä¸ãã¦ã
FirstServer ããååã®ãã¨ã大éã®ãã©ã¦ã¶ããã¢ã¯ã»ã¹ããã¨ãããè² è·ãã¹ããããæ©ä¼ãããã¾ããã
çµæã¯ä»¥ä¸ã§ããããã¾ã§ã SlideStream ã®çµæã§ãã£ã¦ããã以ä¸ã®ãã®ã示ãæå³ã¯æãã¾ããã
ã°ã©ã㯠DTrace(Joyent ã® Bryan Cantrill ãèæ¡ãããã¬ã¼ã¹ãã¼ã«)ãåãåºãããã¼ã¿ãã°ã©ãåãããã®ã§ã
Node Ninja ã® Analytics ç»é¢ããè¦ãã(ä¸é¨ã¯è¦ããªããã®ããã)ãã®ã§ãã
ãã®ã°ã©ããããã©ããã£ããã¨ãèªã¿åãããã«ã¤ãã¦ã¯ãä¸ã®äººã§ãã @vanx2 ããã«è²ã
æãã¦ãããã¾ããã
ã»ã¨ãã©ãã®åã売ãã«ãªã£ã¦ãã¾ãã¾ãããæ¸ãããã¨æãã¾ãã
ãã¹ãæ¡ä»¶
- ï¼ï¼åã«ããã£ã¦æ¥ç¶æ°ãå¢ããã¦ãããæçµçã«ã¯ 1000 ç¨åº¦ã® WebSocket ã³ãã¯ã·ã§ã³ãå¼µã£ãã
- ãã®ä¸ã§ SlideStream ã使ã£ããªã¢ã«ã¿ã¤ã ã³ã¼ãã£ã³ã°ã®ã»ãã·ã§ã³ãããªãã¼ãµã«ããã
- Node.js ã®ããã»ã¹ã¯ä¸ã¤ãããã¯ã« Redis ãå©ç¨ãå©ç¨ãã¦ããªãã MongoDB ãèµ·åãã¦ããã
çµæ
çµæã¯ä»¥ä¸ã§ãããªãããã®ãã¹ãã®éããªãã¼ãµã«ã® Viewer ã«ã¯ãã¹ã©ã¤ããåé¡ãªããªã¢ã«ã¿ã¤ã æã§è¦ãã¦ãããã¨ã確èªãã¦ãã¾ãã
ã°ã©ã詳細(åã°ã©ãã¯æ¯ç§åä½)
å·¦ä¸ãã
- [TCP] Accepts / remote IP(TCPæ¥ç¶ç¢ºç«æ° / IP)
- åä½æéæ¯ã®æ¥ç¶æ°ãªã®ã§ããã¢ä¸ã«æ¥ç¶ãã©ãã©ãå¢ãã¦ãã£ã¦ããã
- [Network interface] VNIC bytes sent and received / sent and received(ãã¼ã¿éåä¿¡ãã¤ãæ° / éä¿¡ã»åä¿¡)
- ç´ 500KB/sec ãããã®ãã¼ã¿ãéããã¦ãããã»ã¨ãã©ãããã¹ããã¼ã¿ãªã®ã§ããã«ããã¯ã«ãªããããªéã§ã¯ãªãã£ã
- [Filesystem] logical read/write operations / app name(è«ççãªèªã¿æ¸ãæ° / ããã»ã¹å)
- ãã¡ã¤ã« I/O ã®åæ°ã¯å°ãªããããã«ããã¯ã«ãªããããªéã§ã¯ãªãã£ã
å³ä¸ãã
- [CPU] thread executions / app name(CPUã¹ã¬ããã®å®è¡æ° / ããã»ã¹å)
- mongod ãå®å¸¸çã«ä½ããå®è¡ããNode ãä¸éã«æ¯ãã¦ãããRedis ã¯ã»ã¨ãã© CPU ã使ã£ã¦ããªããè·³ãã¦ããã®ã¯utmpd ã¨ããç£è¦ããã»ã¹
- [CPU] aggregated CPU usage / zone name(CPUå©ç¨ç / ä»®æ³ãã·ã³)
- ãµã¼ãå ¨ä½ã§å®å¸¸çã« 25% ç¨åº¦ä½¿ããã¦ãã
- [Memory] resident set size / zone name(ã¡ã¢ãªä½¿ç¨ãã¤ãæ° / ä»®æ³ãã·ã³)
- ãµã¼ãå ¨ä½ã§ 200MB ç¨åº¦ã(ãã®ä¸ã§ Node+Redis ãæ¶è²»ããã¡ã¢ãªã¯ 50MB ç¨åº¦ã§ãã£ãã¨ã®ãã¨ã§ãã)
èå¯
CPU, ãã£ã¹ã¯I/O, ãããã¯ã¼ã¯I/O ã®è² è·ã¯å®å¸¸çã«ä½ããããã«ããã¯ã«ãªããããªç¶æ
ã«ã¯è³ã£ã¦ããªãã
ã¾ãã¡ã¢ãªã 1000 ã³ãã¯ã·ã§ã³ã§ããµã¼ãå
¨ä½ã 200MB ç¨åº¦ãªã®ã«å¯¾ãã Node(+ Redis)ãèªä½ãæ¶è²»ããã¡ã¢ãªã¯ 50MB ç¨åº¦ã ã£ãã
MongoDB ã MySQL ãè¦ãããããªãã¼ã¿ã®æ°¸ç¶åã¨ãã®ãã£ãã·ã¥ãªã©ãã SlideStream ã«ã¯ç¡ãã£ããããã¡ã¢ãªã File I/O ã®è² è·ãå°ãªãã®ã¯å½ããåã¨è¨ãã°å½ããåã§ã¯ããã
ããã Apache ã®å ´å 1 ã³ãã¯ã·ã§ã³ã§ 5MB ã»ã©æ¶è²»ãã(親ããã»ã¹ãèªã¿è¾¼ãã¢ã¸ã¥ã¼ã«ãªã©ã«ãã£ã¦å¤§ããå¤ãã) ã¨ã®ãã¨ã§ãããããç°å¢ã§ SlideStream ãåãã 1000 ç¨åº¦ã®ãªã¯ã¨ã¹ãããã£ããããã£ã¨ã¡ã¢ãªãæ¶è²»ããã¨èããããã
å°ãªãã¨ãå
¨ä½çã«ãªã½ã¼ã¹ã®æ¶è²»ã¯å¯¾ãããã¨ãªãã£ãã¨è¨ããã®ã§ã¯ãªãã§ããããã
Stream Based Application
æå¾ã«ä»å¾ã®è©±ã§ãã
ä»åä½ã£ã SlideStream ãããªãã¼ã«ã¯ãã½ã¼ã¹ã«éè¤ãå¤ãæãã¾ãã
ããã¯ãã¯ã©ã¹ã£ã½ãã¡ã½ãããæ½è±¡åã§ãã¦ãã
ããã«ã¤ãã³ãããã¾ãæ½è±¡åãããã¦ããªããããã大ãããªãã¨æãã¦ãã¾ããã
ã¾ããçµ±ä¸ããã¤ã³ã¿ãã§ã¼ã¹ãããã¨ãè²ã
ã¨æããã¨ã¯ééãæãã¾ããã
ããã§ã Node.js ã®ã㤠Stream ãæ´»ç¨ã§ããã¨æãã¾ãã
Node.js ã® Stream ã¯ãã¾ã話ãåºã¦ããªãã£ãã®ã§ãã¢ãã«ã¬ã§æ¸ãã¾ããã
ãã¡ããèªãã§ä¸ããã
Node.js の Stream API で「データの流れ」を扱う方法 - Block Rockin’ Codes
ããã«æ¸ããããã«ããã¼ã¿ã®æµããçµ±ä¸ããã¤ã³ã¿ãã§ã¼ã¹ã§æ±ãããã®ä»çµã¿ã§ãã
SlideStream ã®ã½ã¼ã¹ä¸ã xxStream ã¨ãããªãã¸ã§ã¯ããããã¤ãåºã¦ãã¾ããã
ãã®é ã¯ã¾ã Stream ã®ç解ãæµ
ããã¤ã³ã¿ãã§ã¼ã¹ã«åã£ã¦ã¯ãã¾ããã
ãããããããããã¨ã¯å²ã¨åãæãã«ã¯ãªã£ã¦ããã®ã§ãä»ãªãæ¸ãæããé£ããã¯ãªãã§ãããã
Stream èªä½ã¯ã¾ã ã¾ã è°è«ã®ä½å°ã®ãããã®ã§ãããå人çã«ã¯éè¦ã«ãªã£ã¦ããã¨æã£ã¦ãã¾ãã
ã¹ãã¼ãã¬ã¹ã¨ã¹ãã¼ããã«
ããã¾ã§ã¯ ãHTTP ã¯ã¹ãã¼ãã¬ã¹ã§ãããã¨ããåæããå
¨ã¦ã® Web ã¢ã¼ããã¯ãã£ã®æ ¹å¹¹ã«æã£ãã¨æãã¾ãã
Cookie ãã¼ã¹ã®ã»ãã·ã§ã³ããç»é¢é·ç§»ã¨ããè¨è¨ããåºæ¬ãã®åæã®ä¸ã§ã¤ãããã
Web Application Framework (WAF)ãªãããããã«æé©åããã¦ããã¨æãã¾ãã
REST ããã°ãããèãæ¹ã§ãã
Ajax ãåºã¦ãã¦ããåºæ¬ã¯ãã®ãªã½ã¼ã¹ãéåæã«åå¾ããã¨ãã£ã使ãæ¹ããå§ã¾ã£ã¦ã
ã¾ã ãã®æ ãåºãªãå ´é¢ãå¤ãã§ãã
ãããã WebSocket ã¯ã³ãã¯ã·ã§ã³ãä¿æããã¹ãã¼ããã«ãªãããã³ã«ã§ãã
ããã§å®è£
ããã¢ããªã±ã¼ã·ã§ã³ããå¾æ¥ã® WAF ã®æ ã§èãããã¨ã¯ã
ã¡ãã£ã¨é£ãã®ããªã¨è¨ãããããæ ãæ¡å¤§ãããªããå®è£
ãå¤ããªãã¨ãããªããããããªãã
ä»ã®èªåã§ã¯ãã¾ã çµè«ã¯åºãã¦ãã¾ãããããã㧠Stream ã¯ä¸ã¤éè¦ãªãã¼ã¯ã¼ãã«ãªãã¨æãã¾ãã
Practice
Stream ãç¨ãã¦ã以ä¸ã®ããã«èãã転æãã¾ãã
ãå ¨ã¦ã®ãªã½ã¼ã¹ã¯ã Stream ã§ããã
ãªã½ã¼ã¹ã¯ REST ãªã©ã®è°è«ã«åºããã®ãªã½ã¼ã¹ã§ãã
ããã¯ãã£ããã§ã twitter Streaming ã§ããããããã¯ã©ã¤ã¢ã³ããããµã¼ããã¨ããç²åº¦ãããå¾ã¾ãã
ã¨ãããä»åã®ããã«é£ç¶ãã¦ãã¼ã¿ãçæãããã®ã«å½ã¦ã¯ããã¨è¦ãã¦ãã¾ãã
ããã§ãå ¨ã¦ã Stream ã¨ãã¦æ½è±¡åãã¦æ±ããã¨ããã¢ããã¼ã·ã§ã³ã§èããã®ãæä½ã® Stream.IO ã§ãã
Stream.IO というものを作ってます。 - Block Rockin’ Codes
ã¾ã ã¾ã ãããããã§ãããããããã¯ä»å¾ãªã¢ã«ã¿ã¤ã Web ãèå¯ããä¸ã§ã
éè¦ãªãã¨ãè²ã
æ°ã¥ããã¨æå¾
ãã¦ãããã
æåããã°ã SlideStream çãªãã®ã Stream ãã¼ã¹ã®ã¢ã¼ããã¯ãã£ã§ç°¡åã«ä½ããããããã¾ããã
ã¾ã ã¾ã ãå®è£
ã¯ã ããã¨ããã¾ã§è¡ã£ã¦ãªãã®ã§ã
ããã«ã¤ãã¦ã¯ãã¾ãå¥ã§æ¸ãããã¨æãã¾ãã
conclusion or afterword
ãã£ããé·ããªã£ã¦ãã¾ãã¾ãããã
Node.js 㨠Socket.IO ãç¨ãã SlideStream ã®å®è£
ããå¾ãããã
ã"ãªã¢ã«ã¿ã¤ã Web" ã«é¢ãããã©ã¯ãã£ã¹ãã®ã¢ã¦ããããã§ããã
Node.js 㨠Socket.IO ãã Stream.IO ã«è³ã¾ã§ã
ä»å¹´ï¼å¹´éåãçµãã§ãããã¨ãæ£å¸ãããè¯ãæ©ä¼ã«ãªã£ãã®ã§å人çã«ã¯ããã£ãã§ãã
ã¾ããä»åã®èå¯ã«ã¯ãå¤åã«è°è«ã®ä½å°ãæ®ã£ã¦ããããè²ã
ééããããã¨æãã¾ãã
ææãã³ã¡ã³ããªã©ãªãã¹ããã£ã¼ãããã¯ãããããã¨ãèªåãå
ã«é²ã糧ã«ãªãã¨æãã®ã§ãã§ããã°ãé¡ããããã§ãã
ããã¦ããããè¨äºããã¾ã ã¾ã çºå±éä¸ãª ããªã¢ã«ã¿ã¤ã Webã ã«ã¤ãã¦ã
è°è«ãã¦è¡ããããå°ã¨ãªãã°ã¨æãã¾ãã