Socket.ioãšã¯ïŒ
ãªã¢ã«ã¿ã€ã éä¿¡ãæ±ããããçŸä»£ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã«ãããŠãSocket.ioã¯éåžžã«éèŠãªåœ¹å²ãæãããŠããŸããããã§ã¯ãSocket.ioã®åºæ¬ã«ã€ããŠè©³ãã解説ããŸãã
ãªã¢ã«ã¿ã€ã éä¿¡ã®éèŠæ§
çŸä»£ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã¯ããŠãŒã¶ãŒãšã®å³ææ§ã®é«ãåæ¹åéä¿¡ãæ±ããããã±ãŒã¹ãå¢ããŠããŸããäŸãã°ããã£ããã¢ããªããªã¢ã«ã¿ã€ã éç¥ãå ±åç·šéããŒã«ããªã³ã©ã€ã³ã²ãŒã ãªã©ããã®ä»£è¡šäŸã§ãã
åŸæ¥ã®HTTPéä¿¡ã§ã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ãããµãŒããŒãã¬ã¹ãã³ã¹ãè¿ããšããé察称çãªéä¿¡ã¢ãã«ã§ãããããããããã§ã¯å³ææ§ãæ±ããããã¢ããªã±ãŒã·ã§ã³ã«ã¯äžåãã§ãã
ãªã¢ã«ã¿ã€ã éä¿¡ã¯ããŠãŒã¶ãŒäœéšã®åäžã«å¯äžããããã€ã³ã¿ã©ã¯ãã£ãã§åå¿æ§ã®é«ããµãŒãã¹ãæäŸããããšãã§ããŸããããã«ããããŠãŒã¶ãŒã®ãšã³ã²ãŒãžã¡ã³ããåäžããã¢ããªã±ãŒã·ã§ã³ã®å©çšé »åºŠãæºè¶³åºŠãé«ãŸãã®ã§ãã
Socket.ioã®åºæ¬æ©èœ
Socket.ioã¯ããªã¢ã«ã¿ã€ã éä¿¡ãç°¡åã«å®çŸããããã®ã©ã€ãã©ãªã§ããäž»ã«ä»¥äžã®ãããªåºæ¬æ©èœãæäŸããŠããŸãã
1. åæ¹åéä¿¡
Socket.ioã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®åæ¹åéä¿¡ãå®çŸããŸããããã«ãããã¯ã©ã€ã¢ã³ãããã®ãªã¯ãšã¹ããåŸ
ã€ããšãªãããµãŒããŒããã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžãéä¿¡ããããšãå¯èœã§ãã
2. ã€ãã³ãé§åã¢ãã«
Socket.ioã¯ãã€ãã³ãé§ååã®éä¿¡ã¢ãã«ãæ¡çšããŠããŸããã¯ã©ã€ã¢ã³ããšãµãŒããŒéã§çºçããæ§ã
ãªã€ãã³ãïŒäŸïŒæ¥ç¶ãåæãã¡ãã»ãŒãžéä¿¡ãªã©ïŒã«å¯ŸããŠããªã¹ããŒãèšå®ããç¹å®ã®åŠçãè¡ãããšãã§ããŸãã
3. åå空éïŒNamespaceïŒ
åå空éã¯ãåäžã®æ¥ç¶ãè€æ°ã®è«çãã£ãã«ã«åå²ããããã®æ©èœã§ããããã«ãããåããµãŒããŒå
ã§ç°ãªãæ©èœãã³ã³ããŒãã³ããåé¢ããŠç®¡çããããšãã§ããŸãã
4. ã«ãŒã ïŒRoomïŒ
ã«ãŒã ã¯ãç¹å®ã®ã¯ã©ã€ã¢ã³ãã°ã«ãŒãã«ã¡ãã»ãŒãžãéä¿¡ããããã®æ©èœã§ããããã«ããããã£ããã«ãŒã ãç¹å®ã®ãŠãŒã¶ãŒã°ã«ãŒãã«ã®ã¿ã¡ãã»ãŒãžããããŒããã£ã¹ãããããšãã§ããŸãã
5. èªååæ¥ç¶
Socket.ioã¯ãæ¥ç¶ãåããå Žåã§ãèªåçã«åæ¥ç¶ãè©Šã¿ãæ©èœãæã£ãŠããŸããããã«ããããããã¯ãŒã¯ã®äžå®å®æ§ã«å¯Ÿããèæ§ãåäžããŸãã
6. è·šãã©ãŠã¶äºææ§
Socket.ioã¯ãWebSocketã«å¯Ÿå¿ããŠããªããã©ãŠã¶ã§ãããã©ãŒã«ããã¯ã¡ã«ããºã ãçšããŠãªã¢ã«ã¿ã€ã éä¿¡ãå®çŸããŸããããã«ãããå€ããã©ãŠã¶ãã¢ãã€ã«ããã€ã¹ã§ãå©çšå¯èœã§ãã
WebSocketãšã®éã
Socket.ioã¯WebSocketãããŒã¹ã«ããŠããŸãããäž¡è ã«ã¯ããã€ãã®éèŠãªéãããããŸãã
1. ãããã³ã«ã®ã¬ã€ã€ãŒ
WebSocketã¯ãäœã¬ãã«ã®ãããã³ã«ã§ããããªã¢ã«ã¿ã€ã éä¿¡ãå®çŸããããã®åºæ¬çãªæ段ãæäŸããŸããäžæ¹ãSocket.ioã¯ããã®äžã«æ§ç¯ãããé«ã¬ãã«ã®ã©ã€ãã©ãªã§ãããåæ¹åéä¿¡ãããç°¡åã«å®è£
ããããã®æ©èœãå€æ°æäŸããŸãã
2. ãã©ãŒã«ããã¯ã¡ã«ããºã
WebSocketã¯ããã©ãŠã¶ãWebSocketãããã³ã«ããµããŒãããŠããªãå Žåã«ã¯åäœããŸãããããããSocket.ioã¯ãHTTPãã³ã°ããŒãªã³ã°ãªã©ã®ãã©ãŒã«ããã¯ã¡ã«ããºã ãæã£ãŠãããããããå€ãã®ç°å¢ã§å®å®ããŠåäœããŸãã
3. 簡䟿ãªAPI
Socket.ioã¯ãã€ãã³ãé§ååã®APIãæäŸããŠãããå®è£
ãéåžžã«ã·ã³ãã«ã§ããWebSocketã¯ãããäœã¬ãã«ã®APIãæäŸããŠãããããå®è£
ã«ã¯ããå€ãã®ã³ãŒããå¿
èŠã§ãã
4. è¿œå æ©èœ
Socket.ioã¯ãåå空éãã«ãŒã ãèªååæ¥ç¶ãªã©ã®è¿œå æ©èœãæäŸããŠããŸããããã«ãããéçºè
ã¯è€éãªãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ãç°¡åã«æ§ç¯ããããšãã§ããŸãã
Socket.ioã®ã€ã³ã¹ããŒã«ãšèšå®
Socket.ioã䜿ã£ãŠãªã¢ã«ã¿ã€ã éä¿¡ãå®çŸããããã«ã¯ããŸãNode.jsç°å¢ãæŽããSocket.ioãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãããã®åŸããµãŒããŒãµã€ããšã¯ã©ã€ã¢ã³ããµã€ãã®èšå®ãè¡ããå®éã«åäœãããµã³ãã«ã³ãŒããäœæããŠãããŸãã
Node.jsãšSocket.ioã®ã€ã³ã¹ããŒã«
ãŸããNode.jsãã€ã³ã¹ããŒã«ããŸããNode.jsã¯JavaScriptã®ã©ã³ã¿ã€ã ç°å¢ã§ããµãŒããŒãµã€ãã®JavaScriptã³ãŒããå®è¡ããããã«å¿ èŠã§ããå ¬åŒãµã€ãããé©åãªããŒãžã§ã³ãããŠã³ããŒãããŠã€ã³ã¹ããŒã«ããŸãã
次ã«ããããžã§ã¯ããã£ã¬ã¯ããªãäœæããNode.jsã®ããã±ãŒãžãããŒãžã£ã§ããnpmã䜿ã£ãŠåæèšå®ãè¡ããŸãã
mkdir my-socket-app
cd my-socket-app
npm init -y
npm init -y
ã³ãã³ãã¯ãããã©ã«ãèšå®ã§package.json
ãã¡ã€ã«ãäœæããŸãã次ã«ãSocket.ioãã€ã³ã¹ããŒã«ããŸãã
npm install socket.io
ããã§Socket.ioã®ã€ã³ã¹ããŒã«ã¯å®äºã§ãã次ã«ããµãŒããŒãµã€ããšã¯ã©ã€ã¢ã³ããµã€ãã®èšå®ãè¡ããŸãã
ãµãŒããŒãµã€ãã®èšå®
ãŸãããµãŒããŒãµã€ãã®èšå®ãè¡ããŸãã以äžã®ãããªãã¡ã€ã«æ§æãäœæããŸãã
my-socket-app/
âââ index.js
âââ public/
âââ index.html
index.js
ãã¡ã€ã«ã«ãµãŒããŒãµã€ãã®ã³ãŒããèšè¿°ããŸãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
io.emit('chat message', msg);
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ãã®ã³ãŒãã¯ãExpressã䜿ã£ãŠç°¡åãªWebãµãŒããŒãäœæããSocket.ioãèšå®ãããã®ã§ããã¯ã©ã€ã¢ã³ããæ¥ç¶ãããšconnection
ã€ãã³ããçºçããã¯ã©ã€ã¢ã³ããåæãããšdisconnect
ã€ãã³ããçºçããŸãããŸããchat message
ã€ãã³ãããªã¹ã³ããŠãåä¿¡ããã¡ãã»ãŒãžãå
šãŠã®ã¯ã©ã€ã¢ã³ãã«ãããŒããã£ã¹ãããŠããŸãã
ã¯ã©ã€ã¢ã³ããµã€ãã®èšå®
次ã«ãã¯ã©ã€ã¢ã³ããµã€ãã®èšå®ãè¡ããŸããpublic/index.html
ãã¡ã€ã«ã«ä»¥äžã®ã³ãŒããèšè¿°ããŸãã
<!DOCTYPE html>
<html>
<head>
<title>Socket.io Chat</title>
<style>
/* ç°¡åãªã¹ã¿ã€ã«èšå® */
ul { list-style-type: none; padding: 0; }
li { padding: 8px; margin-bottom: 10px; background: #f4f4f4; }
input { padding: 10px; width: 300px; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
document.getElementById('messages').appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>
</body>
</html>
ãã®HTMLãã¡ã€ã«ã§ã¯ãã¯ã©ã€ã¢ã³ããµã€ãã®Socket.ioã©ã€ãã©ãªãèªã¿èŸŒã¿ãã¡ãã»ãŒãžã®éåä¿¡ãè¡ãã·ã³ãã«ãªãã£ããã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããŠããŸãããã©ãŒã ãéä¿¡ãããšãchat message
ã€ãã³ãããµãŒããŒã«éä¿¡ãããå
šãŠã®ã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžã衚瀺ãããŸãã
åºæ¬çãªãµã³ãã«ã³ãŒã
äžèšã®èšå®ãè¡ã£ãåŸã以äžã®ã³ãã³ãã§ãµãŒããŒãèµ·åããŸãã
node index.js
ãã©ãŠã¶ã§http://localhost:3000
ã«ã¢ã¯ã»ã¹ãããšããã£ããã€ã³ã¿ãŒãã§ãŒã¹ã衚瀺ãããŸããè€æ°ã®ãã©ãŠã¶ã¿ããéããšããªã¢ã«ã¿ã€ã ã§ã¡ãã»ãŒãžãéåä¿¡ãããæ§åã確èªã§ããŸãã
ãã®åºæ¬çãªãµã³ãã«ã³ãŒãã¯ãSocket.ioã®åºæ¬æ©èœãå©çšããã·ã³ãã«ãªãã£ããã¢ããªã±ãŒã·ã§ã³ã®å®è£ äŸã§ãããããããããè€éãªãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ãéçºããããã®åºç€ãåŠã¶ããšãã§ããŸãã
åºæ¬çãªäœ¿ãæ¹
Socket.ioãå©çšããŠãªã¢ã«ã¿ã€ã éä¿¡ãè¡ãããã«ã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®æ¥ç¶ãã€ãã³ãã®éåä¿¡ãåå空éãšã«ãŒã ã®äœ¿çšãã¡ãã»ãŒãžãããŒããã£ã¹ããªã©ã®åºæ¬çãªæ©èœãç解ããããšãéèŠã§ããããã§ã¯ãããããã®æ©èœã«ã€ããŠè©³ãã解説ããŸãã
ãµãŒããŒãšã¯ã©ã€ã¢ã³ãã®æ¥ç¶
Socket.ioã䜿çšããããã«ã¯ããŸããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®æ¥ç¶ã確ç«ããå¿ èŠããããŸããåè¿°ã®åºæ¬èšå®ã«åºã¥ããŠããµãŒããŒãµã€ããšã¯ã©ã€ã¢ã³ããµã€ãã®æ¥ç¶ãèšå®ããŸãã
ãµãŒããŒãµã€ãã®æ¥ç¶èšå®
ãµãŒããŒãµã€ãã§ã¯ãsocket.io
ã©ã€ãã©ãªãå©çšããŠã¯ã©ã€ã¢ã³ãããã®æ¥ç¶ãåŸ
ã¡åããŸãã以äžã«åºæ¬çãªæ¥ç¶èšå®ã®ã³ãŒãã瀺ããŸãã
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
ãã®ã³ãŒãã§ã¯ãã¯ã©ã€ã¢ã³ããæ¥ç¶ããŠãããšãã«connection
ã€ãã³ããçºçããã¯ã©ã€ã¢ã³ããåæãããšãã«disconnect
ã€ãã³ããçºçããŸãã
ã¯ã©ã€ã¢ã³ããµã€ãã®æ¥ç¶èšå®
ã¯ã©ã€ã¢ã³ããµã€ãã§ã¯ãSocket.ioã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªãå©çšããŠãµãŒããŒã«æ¥ç¶ããŸãã以äžã«åºæ¬çãªæ¥ç¶èšå®ã®ã³ãŒãã瀺ããŸãã
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
ãã®ã³ãŒãã¯ããµãŒããŒã«å¯ŸããŠèªåçã«æ¥ç¶ãè©Šã¿ãŸããæ¥ç¶ãæåãããšããµãŒããŒãµã€ãã®connection
ã€ãã³ããããªã¬ãŒãããŸãã
ã€ãã³ãã®éåä¿¡
Socket.ioã®åŒ·åãªç¹åŸŽã®äžã€ã¯ãã€ãã³ãé§ååã®éä¿¡ã¢ãã«ããµããŒãããŠããããšã§ããã€ãã³ãã®éåä¿¡ã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã§åæ¹åã«è¡ãããŸãã
ãµãŒããŒãµã€ãã®ã€ãã³ãéåä¿¡
ãµãŒããŒãµã€ãã§ã¯ãç¹å®ã®ã€ãã³ãããªã¹ã³ããããã«å¿ããŠåŠçãè¡ããŸãããŸããã€ãã³ããã¯ã©ã€ã¢ã³ãã«éä¿¡ããããšãã§ããŸãã
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
io.emit('chat message', msg); // ã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžãéä¿¡
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
ãã®äŸã§ã¯ãã¯ã©ã€ã¢ã³ãããchat message
ã€ãã³ããåä¿¡ãããã®ã¡ãã»ãŒãžãå
šãŠã®ã¯ã©ã€ã¢ã³ãã«ãããŒããã£ã¹ãããŠããŸãã
ã¯ã©ã€ã¢ã³ããµã€ãã®ã€ãã³ãéåä¿¡
ã¯ã©ã€ã¢ã³ããµã€ãã§ã¯ãç¹å®ã®ã€ãã³ãããªã¹ã³ããããã«å¿ããŠåŠçãè¡ããŸãããŸããã€ãã³ãããµãŒããŒã«éä¿¡ããããšãã§ããŸãã
<script>
var socket = io();
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
document.getElementById('messages').appendChild(item);
});
document.getElementById('form').addEventListener('submit', function(e) {
e.preventDefault();
var input = document.getElementById('input');
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
</script>
ãã®äŸã§ã¯ããã©ãŒã ãéä¿¡ããããšãã«chat message
ã€ãã³ãããµãŒããŒã«éä¿¡ãããµãŒããŒããã®chat message
ã€ãã³ããåä¿¡ããŠã¡ãã»ãŒãžã衚瀺ããŠããŸãã
åå空éãšã«ãŒã
Socket.ioã§ã¯ãåå空éãšã«ãŒã ãå©çšããããšã§ãããæè»ãªéä¿¡ãå®çŸã§ããŸãã
åå空éïŒNamespaceïŒ
åå空éã¯ãåäžã®æ¥ç¶ãè€æ°ã®è«çãã£ãã«ã«åå²ããããã®æ©èœã§ããããã©ã«ãã§ã¯/
ãšããåå空éã䜿çšãããŸãããç¬èªã®åå空éãå®çŸ©ããããšãã§ããŸãã
const nsp = io.of('/my-namespace');
nsp.on('connection', (socket) => {
console.log('someone connected to /my-namespace');
socket.on('my event', (data) => {
console.log('my event:', data);
});
});
ã¯ã©ã€ã¢ã³ããµã€ãã§ã¯ãç¹å®ã®åå空éã«æ¥ç¶ããå¿ èŠããããŸãã
<script>
var socket = io('/my-namespace');
socket.emit('my event', {data: 'test data'});
</script>
ã«ãŒã ïŒRoomïŒ
ã«ãŒã ã¯ãç¹å®ã®ã¯ã©ã€ã¢ã³ãã°ã«ãŒãã«ã¡ãã»ãŒãžãéä¿¡ããããã®æ©èœã§ããã¯ã©ã€ã¢ã³ãã¯ãç¹å®ã®ã«ãŒã ã«åå ããããšãã§ããŸãã
io.on('connection', (socket) => {
socket.join('room1');
socket.on('chat message', (msg) => {
io.to('room1').emit('chat message', msg); // ç¹å®ã®ã«ãŒã ã«ã¡ãã»ãŒãžãéä¿¡
});
});
ã¯ã©ã€ã¢ã³ããµã€ãã§ã¯ãç¹ã«è¿œå ã®èšå®ã¯å¿ èŠãããŸããã
ã¡ãã»ãŒãžãããŒããã£ã¹ã
ã¡ãã»ãŒãžãããŒããã£ã¹ãã¯ãç¹å®ã®ã€ãã³ããçºçããéã«ãå šãŠã®ã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžãéä¿¡ããæ©èœã§ããSocket.ioã§ã¯ã以äžã®ããã«ãããŒããã£ã¹ããè¡ããŸãã
ãµãŒããŒãµã€ãã®ãããŒããã£ã¹ã
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg); // å
šãŠã®ã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžããããŒããã£ã¹ã
});
});
ã¯ã©ã€ã¢ã³ããµã€ãã®ãããŒããã£ã¹ã
ã¯ã©ã€ã¢ã³ããµã€ãã§ã¯ãåä¿¡ãããããŒããã£ã¹ãã¡ãã»ãŒãžãåŠçããŸãã
<script>
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
document.getElementById('messages').appendChild(item);
});
</script>
以äžã®ããã«ãSocket.ioãå©çšãããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®æ¥ç¶ãã€ãã³ãã®éåä¿¡ãåå空éãšã«ãŒã ãã¡ãã»ãŒãžãããŒããã£ã¹ãã®åºæ¬çãªäœ¿ãæ¹ãç解ããããšã§ãããé«åºŠãªãªã¢ã«ã¿ã€ã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®éçºãå¯èœã«ãªããŸãã
å®è·µçãªSocket.ioã®æŽ»çšäŸ
Socket.ioã¯å€ãã®ãªã¢ã«ã¿ã€ã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã«é©çšã§ããŸããããã§ã¯ãå ·äœçãªæŽ»çšäŸãšããŠããã£ããã¢ããªããªã¢ã«ã¿ã€ã ããŒã¿è¡šç€ºããªã³ã©ã€ã³ã²ãŒã ãã³ã©ãã¬ãŒã·ã§ã³ããŒã«ãIoTããã€ã¹ãšã®é£æºã«ã€ããŠè©³ãã解説ããŸãã
ãã£ããã¢ããªã®æ§ç¯
æŠèŠ
ãã£ããã¢ããªã¯ããªã¢ã«ã¿ã€ã éä¿¡ã®ä»£è¡šçãªã¢ããªã±ãŒã·ã§ã³ã§ããSocket.ioã䜿ãããšã§ãã¡ãã»ãŒãžã®å³æéåä¿¡ãç°¡åã«å®çŸã§ããŸãã
ãµãŒããŒãµã€ã
以äžã«ãç°¡åãªãã£ãããµãŒããŒã®ã³ãŒãã瀺ããŸãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ã¯ã©ã€ã¢ã³ããµã€ã
次ã«ãã¯ã©ã€ã¢ã³ããµã€ãã®ã³ãŒãã§ãã
ãã®ã·ã³ãã«ãªãã£ããã¢ããªã¯ãSocket.ioã®åºæ¬æ©èœãå©çšããŠããªã¢ã«ã¿ã€ã ã§ã¡ãã»ãŒãžãéåä¿¡ããŸãã
<!DOCTYPE html>
<html>
<head>
<title>Chat App</title>
<style>
ul { list-style-type: none; padding: 0; }
li { padding: 8px; margin-bottom: 10px; background: #f4f4f4; }
input { padding: 10px; width: 300px; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
document.getElementById('messages').appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>
</body>
</html>
ãªã¢ã«ã¿ã€ã ããŒã¿ã®è¡šç€º
æŠèŠ
ãªã¢ã«ã¿ã€ã ããŒã¿ã®è¡šç€ºã¯ãããã·ã¥ããŒããç£èŠã·ã¹ãã ãªã©ã§å©çšãããŸããSocket.ioã䜿ãããšã§ãããŒã¿ã®æŽæ°ãå³åº§ã«ã¯ã©ã€ã¢ã³ãã«åæ ã§ããŸãã
ãµãŒããŒãµã€ã
äŸãã°ãæ ªäŸ¡ããŒã¿ããªã¢ã«ã¿ã€ã ã§æŽæ°ããå Žåã®ãµãŒããŒã³ãŒãã¯ä»¥äžã®éãã§ãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const fetch = require('node-fetch');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('a user connected');
setInterval(async () => {
const response = await fetch('https://api.example.com/stock-price');
const data = await response.json();
socket.emit('stock price', data);
}, 5000);
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ã¯ã©ã€ã¢ã³ããµã€ã
ã¯ã©ã€ã¢ã³ãåŽã§ã¯ããªã¢ã«ã¿ã€ã ã«ããŒã¿ãåä¿¡ããŠè¡šç€ºããŸãã
<!DOCTYPE html>
<html>
<head>
<title>Real-time Stock Prices</title>
</head>
<body>
<h1>Stock Prices</h1>
<ul id="prices"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('stock price', function(data) {
var list = document.getElementById('prices');
list.innerHTML = '';
data.prices.forEach(function(price) {
var item = document.createElement('li');
item.textContent = `${price.symbol}: ${price.value}`;
list.appendChild(item);
});
});
</script>
</body>
</html>
ãªã³ã©ã€ã³ã²ãŒã ã®éçº
æŠèŠ
ãªã³ã©ã€ã³ã²ãŒã ã§ã¯ããã¬ã€ã€ãŒéã®ãªã¢ã«ã¿ã€ã éä¿¡ãäžå¯æ¬ ã§ããSocket.ioãå©çšããããšã§ããã¬ã€ã€ãŒã®äœçœ®æ
å ±ãã¢ã¯ã·ã§ã³ããªã¢ã«ã¿ã€ã ã§å
±æã§ããŸãã
ãµãŒããŒãµã€ã
以äžã¯ãã·ã³ãã«ãªãªã¢ã«ã¿ã€ã ã²ãŒã ãµãŒããŒã®äŸã§ãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
let players = {};
io.on('connection', (socket) => {
console.log('a user connected');
players[socket.id] = { x: 0, y: 0 };
socket.on('move', (data) => {
players[socket.id] = data;
io.emit('update', players);
});
socket.on('disconnect', () => {
console.log('user disconnected');
delete players[socket.id];
io.emit('update', players);
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ã¯ã©ã€ã¢ã³ããµã€ã
ã¯ã©ã€ã¢ã³ãåŽã§ã¯ããã¬ã€ã€ãŒã®åãããµãŒããŒã«éä¿¡ããä»ã®ãã¬ã€ã€ãŒã®åãããªã¢ã«ã¿ã€ã ã§è¡šç€ºããŸãã
<!DOCTYPE html>
<html>
<head>
<title>Real-time Game</title>
<style>
#game { width: 500px; height: 500px; position: relative; }
.player { width: 10px; height: 10px; background: red; position: absolute; }
</style>
</head>
<body>
<div id="game"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var game = document.getElementById('game');
socket.on('update', function(players) {
game.innerHTML = '';
for (var id in players) {
var player = document.createElement('div');
player.className = 'player';
player.style.left = players[id].x + 'px';
player.style.top = players[id].y + 'px';
game.appendChild(player);
}
});
window.addEventListener('keydown', function(e) {
var x = 0, y = 0;
if (e.key === 'ArrowUp') y -= 5;
if (e.key === 'ArrowDown') y += 5;
if (e.key === 'ArrowLeft') x -= 5;
if (e.key === 'ArrowRight') x += 5;
socket.emit('move', { x: x, y: y });
});
</script>
</body>
</html>
ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ã®éçº
æŠèŠ
ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ã§ã¯ããŠãŒã¶ãŒéã®ãªã¢ã«ã¿ã€ã ãªå
±åäœæ¥ãæ±ããããŸããSocket.ioã䜿ãããšã§ãç·šéå
容ã®å³æåæ ãåæãå¯èœã§ãã
ãµãŒããŒãµã€ã
以äžã«ãå
±åç·šéããŒã«ã®åºæ¬çãªãµãŒããŒãµã€ãã³ãŒãã瀺ããŸãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
let documentContent = "";
io.on('connection', (socket) => {
socket.emit('document', documentContent);
socket.on('edit', (content) => {
documentContent = content;
socket.broadcast.emit('document', documentContent);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ã¯ã©ã€ã¢ã³ããµã€ã
ã¯ã©ã€ã¢ã³ãåŽã§ã¯ãç·šéå
容ããµãŒããŒã«éä¿¡ããä»ã®ã¯ã©ã€ã¢ã³ãã«åæ ãããŸãã
<!DOCTYPE html>
<html>
<head>
<title>Collaborative Editor</title>
</head>
<body>
<textarea id="editor" cols="100" rows="20"></textarea>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var editor = document.getElementById('editor');
socket.on('document', function(content) {
editor.value = content;
});
editor.addEventListener('input', function() {
socket.emit('edit', editor.value);
});
</script>
</body>
</html>
IoTããã€ã¹ãšã®é£æº
æŠèŠ
IoTããã€ã¹ãšé£æºããããšã§ããªã¢ã«ã¿ã€ã ã®ããŒã¿åéãå¶åŸ¡ãå¯èœã«ãªããŸããSocket.ioã䜿ã£ãŠãããã€ã¹ããã®ããŒã¿ããªã¢ã«ã¿ã€ã ã«åéããåŠçããããšãã§ããŸãã
ãµãŒããŒãµã€ã
以äžã«ãIoTããã€ã¹ããã®ããŒã¿ãåä¿¡ããåºæ¬çãªãµãŒããŒãµã€ãã³ãŒãã瀺ããŸãã
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('sensor data', (data) => {
console.log('Sensor data:', data);
io.emit('sensor data', data);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ã¯ã©ã€ã¢ã³ããµã€ã
ã¯ã©ã€ã¢ã³ãåŽã§ã¯ãIoTããã€ã¹ããã®ããŒã¿ããªã¢ã«ã¿ã€ã ã§è¡šç€ºããŸãã
<!DOCTYPE html>
<html>
<head>
<title>IoT Data</title>
</head>
<body>
<h1>Sensor Data</h1>
<ul id="data"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var dataList = document.getElementById('data');
socket.on('sensor data', function(data) {
var item = document.createElement('li');
item.textContent = `Temperature: ${data.temperature}, Humidity: ${data.humidity}`;
dataList.appendChild(item);
});
</script>
</body>
</html>
ãã®ããã«ãSocket.ioã䜿ãããšã§æ§ã ãªãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ãç°¡åã«æ§ç¯ããããšãã§ããŸããå掻çšäŸã¯ãå®éã®ãããžã§ã¯ãã«å¿ããŠã«ã¹ã¿ãã€ãºããããšãå¯èœã§ãã次ã®ã»ã¯ã·ã§ã³ã§ã¯ãããã©ãŒãã³ã¹ã®æé©åã«ã€ããŠè©³ãã解説ããŸãã
ããã©ãŒãã³ã¹æé©å
Socket.ioã䜿çšãããªã¢ã«ã¿ã€ã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããã©ãŒãã³ã¹ã®æé©åãéåžžã«éèŠã§ããç¹ã«ãã¹ã±ãŒã©ããªãã£ãè² è·åæ£ããšã©ãŒåŠçããããã°ãããã³ããã©ãŒãã³ã¹ãã¹ãã¯ãã·ã¹ãã ã®å¹ççãªéçšãšãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®åäžã«çŽçµããŸãããã®ã»ã¯ã·ã§ã³ã§ã¯ãããããã®æé©åææ³ã«ã€ããŠè©³ãã解説ããŸãã
ã¹ã±ãŒã©ããªãã£ã®èæ ®
ã¹ã±ãŒã©ããªãã£ãšã¯ãã·ã¹ãã ãè² è·ã«å¿ããŠæ¡åŒµã§ããèœåãæããŸããSocket.ioã䜿çšããå Žåãã¹ã±ãŒã©ããªãã£ãèæ ®ããèšèšãå¿ èŠã§ãã
æ°Žå¹³ã¹ã±ãŒãªã³ã°
Socket.ioãæ°Žå¹³ã¹ã±ãŒãªã³ã°ããããã«ã¯ãè€æ°ã®Node.jsã€ã³ã¹ã¿ã³ã¹ã䜿çšããããããè² è·åæ£ããå¿ èŠããããŸããRedisãªã©ã®ã¡ãã»ãŒãžãããŒã«ãŒã䜿çšããŠãåã€ã³ã¹ã¿ã³ã¹éã§Socket.ioã®ã€ãã³ããåæããŸãã
ã€ã³ã¹ããŒã«ãšèšå®
npm install socket.io-redis redis
ãµãŒããŒãµã€ãã®ã³ãŒãã§Redisã¢ããã¿ãŒãèšå®ããŸãã
const io = require('socket.io')(server);
const redisAdapter = require('socket.io-redis');
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));
ããã«ãããè€æ°ã®Socket.ioãµãŒããŒãRedisãä»ããŠã€ãã³ããå ±æããã¹ã±ãŒã©ããªãã£ã確ä¿ã§ããŸãã
åå空éãšã«ãŒã ã®æŽ»çš
åå空éãšã«ãŒã ã掻çšããããšã§ãç¹å®ã®ã€ãã³ããã¡ãã»ãŒãžã®éä¿¡å ãéå®ããç¡é§ãªãªãœãŒã¹ã®æ¶è²»ãæããããšãã§ããŸãã
const chat = io.of('/chat');
chat.on('connection', (socket) => {
socket.join('room1');
chat.to('room1').emit('message', 'Hello, room1!');
});
è² è·åæ£ã®å®è£
è² è·åæ£ã¯ãã·ã¹ãã å šäœã®è² è·ãåçã«åæ£ããããã«éèŠã§ãã以äžã«ãäžè¬çãªè² è·åæ£ã®æ¹æ³ã玹ä»ããŸãã
ãªããŒã¹ãããã·
NginxãHAProxyãªã©ã®ãªããŒã¹ãããã·ã䜿çšããŠãè€æ°ã®Node.jsã€ã³ã¹ã¿ã³ã¹ã«ãã©ãã£ãã¯ãåæ£ãããŸããNginxã®èšå®äŸã瀺ããŸãã
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
ãã®èšå®ã«ãããNginxãã¯ã©ã€ã¢ã³ãã®ãªã¯ãšã¹ããè€æ°ã®Node.jsãµãŒããŒã«åæ£ããŸãã
Kubernetesã®äœ¿çš
Kubernetesã䜿çšããŠã³ã³ããåãããSocket.ioã¢ããªã±ãŒã·ã§ã³ããããã€ããèªåçã«ã¹ã±ãŒãªã³ã°ãšè² è·åæ£ãè¡ãããšãã§ããŸãã以äžã¯ãåºæ¬çãªãããã€ã¡ã³ãèšå®ã®äŸã§ãã
apiVersion: apps/v1
kind: Deployment
metadata:
name: socket-io-deployment
spec:
replicas: 3
selector:
matchLabels:
app: socket-io
template:
metadata:
labels:
app: socket-io
spec:
containers:
- name: socket-io
image: your-docker-image
ports:
- containerPort: 3000
ããã«ãããKubernetesãæå®ããæ°ã®ã¬ããªã«ãäœæããè² è·åæ£ãè¡ããŸãã
ãšã©ãŒåŠçãšãããã°
Socket.ioã¢ããªã±ãŒã·ã§ã³ã®ä¿¡é Œæ§ãé«ããããã«ã¯ããšã©ãŒåŠçãšãããã°ãäžå¯æ¬ ã§ãã
ãšã©ãŒãã³ããªã³ã°
Socket.ioã§ã¯ãtry...catch
æ§æã䜿çšããŠãšã©ãŒããã£ããããé©åãªãšã©ãŒã¡ãã»ãŒãžãã¯ã©ã€ã¢ã³ãã«éä¿¡ããããšãã§ããŸãã
io.on('connection', (socket) => {
try {
socket.on('event', (data) => {
// ã€ãã³ãåŠç
});
} catch (error) {
console.error('Error occurred:', error);
socket.emit('error', { message: 'An error occurred' });
}
});
ãã®ã³ã°
é©åãªãã®ã³ã°ãè¡ãããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
ããšã©ãŒãææ¡ãããããªããŸããwinston
ãmorgan
ãªã©ã®ãã®ã³ã°ã©ã€ãã©ãªã䜿çšããããšãæšå¥šãããŸãã
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
io.on('connection', (socket) => {
socket.on('event', (data) => {
logger.info('Event received:', data);
});
});
ããã©ãŒãã³ã¹ãã¹ãã®å®æœ
ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãè©äŸ¡ããæ¹åããããã«ã¯ãå®æçãªããã©ãŒãã³ã¹ãã¹ããéèŠã§ãã
ããŒã«ã®éžå®
Socket.ioã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãã¹ãã«ã¯ãk6
ãartillery
ãªã©ã®ããŒã«ãé©ããŠããŸãã
k6ã®äœ¿çšäŸ
ãŸããk6ãã€ã³ã¹ããŒã«ããŸãã
brew install k6
次ã«ããã¹ãã¹ã¯ãªãããäœæããŸãã
import http from 'k6/http';
import { check, sleep } from 'k6';
export default function () {
const url = 'http://localhost:3000';
const res = http.get(url);
check(res, {
'status is 200': (r) => r.status === 200,
});
sleep(1);
}
ãã®ã¹ã¯ãªãããå®è¡ããŠããã©ãŒãã³ã¹ãã¹ããè¡ããŸãã
k6 run script.js
Artilleryã®äœ¿çšäŸ
Artilleryãã€ã³ã¹ããŒã«ããŸãã
npm install -g artillery
次ã«ããã¹ãã¹ã¯ãªãããäœæããŸãã
config:
target: "http://localhost:3000"
phases:
- duration: 60
arrivalRate: 10
scenarios:
- flow:
- get:
url: "/"
ãã®ã¹ã¯ãªãããå®è¡ããŠããã©ãŒãã³ã¹ãã¹ããè¡ããŸãã
artillery run script.yml
ãããã®ããŒã«ã䜿çšããããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãè©äŸ¡ããå¿ èŠãªæ¹åç¹ãç¹å®ããããšãã§ããŸãã
ã»ãã¥ãªãã£å¯Ÿç
ãªã¢ã«ã¿ã€ã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®éçºã«ãããŠãã»ãã¥ãªãã£ã¯æ¥µããŠéèŠã§ããSocket.ioã䜿çšããéã«ããé©åãªã»ãã¥ãªãã£å¯Ÿçãè¬ããããšã§ãããŒã¿ã®ä¿è·ãäžæ£ã¢ã¯ã»ã¹ã®é²æ¢ãå¯èœã«ãªããŸããããã§ã¯ãããŒã¿ã®æå·åãèªèšŒãšèªå¯ãXSSãCSRF察çãã»ãã¥ãªãã£äžã®ãã¹ããã©ã¯ãã£ã¹ã«ã€ããŠè©³ãã解説ããŸãã
ããŒã¿ã®æå·å
ããŒã¿ã®æå·åã¯ãéä¿¡äžã®ããŒã¿ã第äžè ã«èªã¿åãããªãããã«ããããã®éèŠãªå¯Ÿçã§ãã
HTTPSã®äœ¿çš
Socket.ioã¯WebSocketã䜿çšããŠéä¿¡ãè¡ããŸãããéä¿¡å 容ãæå·åããããã«HTTPSã䜿çšããããšãæšå¥šãããŸãã以äžã«ãHTTPSã䜿çšãããµãŒããŒèšå®ã®äŸã瀺ããŸãã
const fs = require('fs');
const https = require('https');
const express = require('express');
const socketIo = require('socket.io');
const app = express();
const server = https.createServer({
key: fs.readFileSync('path/to/your/private.key'),
cert: fs.readFileSync('path/to/your/certificate.crt')
}, app);
const io = socketIo(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
ãã®äŸã§ã¯ãHTTPSã䜿çšããŠãµãŒããŒãèšå®ããSocket.ioã®éä¿¡ãæå·åããŠããŸãã
WebSocketã®ã»ãã¥ãªãã£
WebSocketã¯ãTLSïŒTransport Layer SecurityïŒãå©çšããŠæå·åã§ããŸãããµãŒããŒã®ã»ããã¢ããã¯ä»¥äžã®éãã§ãã
const https = require('https');
const fs = require('fs');
const socketIo = require('socket.io');
const server = https.createServer({
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
});
const io = socketIo(server);
server.listen(3000, () => {
console.log('listening on *:3000');
});
ããã«ãããã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®WebSocketéä¿¡ãæå·åãããŸãã
èªèšŒãšèªå¯ã®å®è£
èªèšŒãšèªå¯ã¯ããŠãŒã¶ãŒãé©åãªæš©éãæã£ãŠããããšã確èªããããã«å¿ èŠã§ãã
JWTïŒJSON Web TokenïŒã®äœ¿çš
JWTã䜿çšããããšã§ããŠãŒã¶ãŒã®èªèšŒãšèªå¯ãå¹ççã«å®è£ ã§ããŸãã以äžã«ãJWTã䜿çšããSocket.ioã®èªèšŒäŸã瀺ããŸãã
ãµãŒããŒãµã€ã
const jwt = require('jsonwebtoken');
const secret = 'your-secret-key';
io.use((socket, next) => {
const token = socket.handshake.query.token;
if (token) {
jwt.verify(token, secret, (err, decoded) => {
if (err) {
return next(new Error('Authentication error'));
}
socket.decoded = decoded;
next();
});
} else {
next(new Error('Authentication error'));
}
}).on('connection', (socket) => {
console.log('a user connected with ID:', socket.decoded.id);
});
ã¯ã©ã€ã¢ã³ããµã€ã
<script src="/socket.io/socket.io.js"></script>
<script>
const token = 'your-jwt-token';
const socket = io.connect('https://your-server.com', {
query: { token: token }
});
</script>
ãã®äŸã§ã¯ãJWTã䜿çšããŠã¯ã©ã€ã¢ã³ããèªèšŒããèªèšŒãããã¯ã©ã€ã¢ã³ãã®ã¿ãæ¥ç¶ã§ããããã«ããŠããŸãã
XSSãCSRF察ç
XSSïŒã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒãCSRFïŒã¯ãã¹ãµã€ããªã¯ãšã¹ããã©ãŒãžã§ãªïŒã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã«å¯Ÿããäžè¬çãªæ»æææ³ã§ãããããã®å¯Ÿçãè¬ããããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ã匷åã§ããŸãã
XSS察ç
XSSæ»æã¯ãæªæã®ããã¹ã¯ãªãããå®è¡ãããããšã«ãã£ãŠçºçããŸãã以äžã«ãåºæ¬çãªXSS察çã瀺ããŸãã
å ¥åã®ãµãã¿ã€ãº
ãŠãŒã¶ãŒããã®å ¥åããŒã¿ããµãã¿ã€ãºããŠãæªæã®ããã¹ã¯ãªãããå«ãŸããªãããã«ããŸãã
const sanitizeHtml = require('sanitize-html');
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
const sanitizedMsg = sanitizeHtml(msg);
io.emit('chat message', sanitizedMsg);
});
});
ãã®äŸã§ã¯ããŠãŒã¶ãŒããåä¿¡ããã¡ãã»ãŒãžããµãã¿ã€ãºããŠããä»ã®ã¯ã©ã€ã¢ã³ãã«éä¿¡ããŠããŸãã
CSRF察ç
CSRFæ»æã¯ããŠãŒã¶ãŒãæå³ããªããªã¯ãšã¹ããéä¿¡ãããããããšã«ãã£ãŠçºçããŸãã以äžã«ãåºæ¬çãªCSRF察çã瀺ããŸãã
CSRFããŒã¯ã³ã®äœ¿çš
CSRFããŒã¯ã³ã䜿çšããŠãæ£åœãªãªã¯ãšã¹ãã§ããããšã確èªããŸãã
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);
app.get('/form', (req, res) => {
res.render('send', { csrfToken: req.csrfToken() });
});
app.post('/process', (req, res) => {
res.send('data is being processed');
});
ã»ãã¥ãªãã£äžã®ãã¹ããã©ã¯ãã£ã¹
æåŸã«ãSocket.ioã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ã匷åããããã®ãã¹ããã©ã¯ãã£ã¹ãããã€ã玹ä»ããŸãã
åžžã«ææ°ã®ããŒãžã§ã³ã䜿çšãã
Socket.ioããã³äŸåã©ã€ãã©ãªã®ææ°ããŒãžã§ã³ã䜿çšããããšã§ãæ¢ç¥ã®è匱æ§ãåé¿ããŸãã
npm update socket.io
ããã©ã«ãã®èšå®ãå€æŽãã
ããã©ã«ãã®èšå®ãå€æŽããã»ãã¥ãªãã£ã匷åããŸããäŸãã°ãCORSããªã·ãŒãé©åã«èšå®ããŸãã
const io = require('socket.io')(server, {
cors: {
origin: "https://your-allowed-origin.com",
methods: ["GET", "POST"]
}
});
äžèŠãªæ©èœãç¡å¹åãã
䜿çšããªãæ©èœã¯ç¡å¹åããŠãæ»æ察象ãæžãããŸãã
io.set('transports', ['websocket']);
ã»ãã¥ãªãã£ãã¹ããå®æçã«å®æœãã
å®æçã«ã»ãã¥ãªãã£ãã¹ããå®æœããŠãæ°ããªè匱æ§ãçºèŠããä¿®æ£ããŸããå°éçãªã»ãã¥ãªãã£ããŒã«ããµãŒãã¹ãå©çšããããšãæšå¥šãããŸãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãSocket.ioã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£å¯Ÿçã«ã€ããŠè©³ãã解説ããŸããããããã®å¯Ÿçãé©çšããããšã§ãããå®å šã§ä¿¡é Œæ§ã®é«ããªã¢ã«ã¿ã€ã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ãéçºããããšãã§ããŸãã次ã®ã»ã¯ã·ã§ã³ã§ã¯ãããããåé¡ãšè§£æ±ºæ¹æ³ã«ã€ããŠè©³ããèŠãŠãããŸãããã
ããããåé¡ãšè§£æ±ºæ¹æ³
Socket.ioã䜿çšããéã«çŽé¢ããããšãå€ãåé¡ãšãã®è§£æ±ºæ¹æ³ã«ã€ããŠè©³ãã解説ããŸãããã®ã»ã¯ã·ã§ã³ã§ã¯ãæ¥ç¶ãåããå Žåã®å¯ŸåŠæ³ãã¡ãã»ãŒãžã®é 延察çãäºææ§ã®åé¡ãããã³ãããã°ããŒã«ã®çŽ¹ä»ãè¡ããŸãã
æ¥ç¶ãåããå Žåã®å¯ŸåŠæ³
Socket.ioã䜿çšããŠãããšãæ¥ç¶ãé »ç¹ã«åããããšããããŸãããã®åé¡ã¯ããããã¯ãŒã¯ã®äžå®å®ãããµãŒããŒåŽã®åé¡ãªã©ãããŸããŸãªèŠå ã«ãã£ãŠåŒãèµ·ããããŸãã
èªååæ¥ç¶ã®èšå®
Socket.ioã«ã¯ãèªååæ¥ç¶æ©èœãçµã¿èŸŒãŸããŠããŸããããã©ã«ãã§ã¯æå¹ã«ãªã£ãŠããŸãããèšå®ã確èªããé©åã«èª¿æŽããããšã§ãæ¥ç¶ãåããå Žåã«èªåçã«åæ¥ç¶ãè©Šã¿ãããšãã§ããŸãã
ã¯ã©ã€ã¢ã³ããµã€ã
const socket = io({
reconnection: true,
reconnectionAttempts: Infinity,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000
});
socket.on('connect_error', (error) => {
console.log('Connection Error:', error);
});
socket.on('reconnect_attempt', () => {
console.log('Reconnection attempt...');
});
ãã®èšå®ã§ã¯ãç¡éã«åæ¥ç¶ãè©Šã¿ãåæ¥ç¶ã®é 延ãèšå®ããŠããŸãã
ãµãŒããŒã®å¥å šæ§ãã§ãã¯
ãµãŒããŒã®å¥å šæ§ãå®æçã«ãã§ãã¯ããå¿ èŠã«å¿ããŠåèµ·åããããšãéèŠã§ããäŸãã°ããµãŒããŒã®è² è·ãé«ãŸã£ãŠããå Žåã«ã¯ããªãœãŒã¹ãè¿œå ããŠã¹ã±ãŒã«ã¢ãŠããããªã©ã®å¯Ÿçãè¬ããŸãã
ã¡ãã»ãŒãžã®é 延察ç
ã¡ãã»ãŒãžã®é 延ã¯ããªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããéèŠãªåé¡ã§ãã以äžã®å¯Ÿçãè¬ããããšã§ãé 延ãæå°éã«æããããšãã§ããŸãã
ãããã¯ãŒã¯ã®æé©å
ãããã¯ãŒã¯ã®æé©åã¯ãé 延ãæžããããã®åºæ¬çãªå¯Ÿçã§ãã以äžã®ãããªæ¹æ³ããããŸãã
CDNã®äœ¿çš
ã³ã³ãã³ãé ä¿¡ãããã¯ãŒã¯ïŒCDNïŒã䜿çšããŠãéçãªãœãŒã¹ã®é ä¿¡ãæé©åãããµãŒããŒã®è² è·ã軜æžããŸãã
ããŒã¿å§çž®
ããŒã¿ãå§çž®ããŠéä¿¡ããããšã§ããããã¯ãŒã¯ã®åž¯åå¹ ãç¯çŽããé 延ãæžå°ãããŸãã
const io = require('socket.io')(server, {
perMessageDeflate: {
threshold: 1024, // å§çž®ããæå°ã¡ãã»ãŒãžãµã€ãº
}
});
ãµãŒããŒãµã€ãã®æé©å
ãµãŒããŒãµã€ãã®åŠçãæé©åããããšãéèŠã§ãã
ã€ãã³ãã«ãŒãã®è² è·è»œæž
éåæåŠçãé©åã«äœ¿çšããã€ãã³ãã«ãŒãã®è² è·ã軜æžããŸãã
const heavyTask = async () => {
return new Promise((resolve) => {
// éãåŠç
resolve(result);
});
};
io.on('connection', (socket) => {
socket.on('heavy task', async () => {
const result = await heavyTask();
socket.emit('task result', result);
});
});
äºææ§ã®åé¡
Socket.ioã¯å€ãã®ç°å¢ã§åäœããŸãããäºææ§ã®åé¡ãçºçããããšããããŸãããããã®åé¡ã解決ããããã®å¯Ÿçãè¬ããŸãã
ãã©ãŒã«ããã¯ã¡ã«ããºã
Socket.ioã¯ãWebSocketããµããŒããããŠããªãå Žåã«ãã©ãŒã«ããã¯ã¡ã«ããºã ãæäŸããŸãããã©ãŒã«ããã¯ã¡ã«ããºã ãé©åã«èšå®ããããšã§ãäºææ§ã®åé¡ãåé¿ããŸãã
const io = require('socket.io')(server, {
transports: ['websocket', 'polling']
});
ããŒãžã§ã³ç®¡ç
Socket.ioã®ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®ããŒãžã§ã³ãäžèŽãããããšãéèŠã§ããç°ãªãããŒãžã§ã³éã§äºææ§ã®åé¡ãçºçããããšããããŸãã
npm install socket.io@latest
npm install socket.io-client@latest
ãããã°ããŒã«ã®çŽ¹ä»
ãããã°ããŒã«ã䜿çšããããšã§ãSocket.ioã¢ããªã±ãŒã·ã§ã³ã®åé¡ãè¿ éã«ç¹å®ãã解決ããããšãã§ããŸãã以äžã«ããã€ãã®æçšãªãããã°ããŒã«ã玹ä»ããŸãã
Socket.io Debug
Socket.ioã«ã¯ãå èµã®ãããã°æ©èœããããŸããç°å¢å€æ°ãèšå®ããããšã§ã詳现ãªãããã°æ å ±ãååŸã§ããŸãã
DEBUG=socket.io* node index.js
ãã®èšå®ã«ãããSocket.ioã®å šãŠã®ãããã°ã¡ãã»ãŒãžãåºåãããŸãã
Chrome DevTools
Chrome DevToolsã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ãããã°ã«éåžžã«æçšã§ããNetworkã¿ãã䜿çšããŠWebSocketéä¿¡ãç£èŠããã¡ãã»ãŒãžã®å 容ãã¿ã€ãã³ã°ã確èªã§ããŸãã
Wireshark
Wiresharkã¯ããããã¯ãŒã¯ãããã³ã«ã¢ãã©ã€ã¶ã§ããããããã¯ãŒã¯ãã©ãã£ãã¯ã詳现ã«è§£æããããã®ããŒã«ã§ããSocket.ioã®éä¿¡ããã£ããã£ããŠãåé¡ã®åå ãç¹å®ããããšãã§ããŸãã
ãŸãšã
Socket.ioã¯ããªã¢ã«ã¿ã€ã éä¿¡ãç°¡åãã€å¹ççã«å®çŸããããã®åŒ·åãªããŒã«ã§ãããã®ã»ã¯ã·ã§ã³ã§ã¯ãSocket.ioã®å©ç¹ãé©çšç¯å²ã®åºããä»åŸã®å±æãšçºå±å¯èœæ§ãããã³ãããªãåŠç¿ãªãœãŒã¹ã«ã€ããŠè©³ãã解説ããŸãã
Socket.ioã®å©ç¹
Socket.ioã䜿çšããããšã§åŸãããå©ç¹ã¯å€æ°ãããŸãã以äžã«ãã®äž»ãªå©ç¹ãæããŸãã
ç°¡åãªå®è£
Socket.ioã¯ãç°¡åã«ãªã¢ã«ã¿ã€ã éä¿¡ãå®è£ ã§ããçŽæçãªAPIãæäŸããŠããŸããããã«ãããéçºè ã¯è€éãªéä¿¡ãããã³ã«ãæèããããšãªããè¿ éã«ãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
åæ¹åéä¿¡ã®ãµããŒã
Socket.ioã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®åæ¹åéä¿¡ããµããŒãããŠããŸããããã«ããããªã¢ã«ã¿ã€ã ã§ã®ããŒã¿éåä¿¡ãå¯èœãšãªããã€ã³ã¿ã©ã¯ãã£ããªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸã§ããŸãã
èªååæ¥ç¶
ãããã¯ãŒã¯æ¥ç¶ãéåããå Žåã§ããSocket.ioã¯èªåçã«åæ¥ç¶ãè©Šã¿ãŸãããã®æ©èœã«ããããŠãŒã¶ãŒãã·ãŒã ã¬ã¹ãªäœéšã享åã§ããããã«ãªããŸãã
é«ãäºææ§
Socket.ioã¯ãWebSocketããµããŒãããŠããªããã©ãŠã¶ã§ããã©ãŒã«ããã¯ã¡ã«ããºã ã䜿çšããŠåäœããŸããããã«ãããå¹ åºãç°å¢ã§ãªã¢ã«ã¿ã€ã éä¿¡ãå®çŸã§ããŸãã
é©çšç¯å²ã®åºã
Socket.ioã¯ããã®æè»æ§ãšåŒ·åãªæ©èœã«ãããæ§ã ãªåéã§æŽ»çšãããŠããŸãã以äžã«ã代衚çãªé©çšç¯å²ã瀺ããŸãã
ãã£ããã¢ããªã±ãŒã·ã§ã³
ãªã¢ã«ã¿ã€ã ãã£ããã¢ããªã±ãŒã·ã§ã³ã¯ãSocket.ioã®å žåçãªäœ¿çšäŸã§ããã¡ãã»ãŒãžã®å³æéåä¿¡ãæ±ãããããããSocket.ioã®åæ¹åéä¿¡æ©èœãéåžžã«æå¹ã§ãã
ãªã¢ã«ã¿ã€ã ããŒã¿è¡šç€º
æ ªäŸ¡ã倩æ°æ å ±ãã¹ããŒãã®è©Šåçµæãªã©ããªã¢ã«ã¿ã€ã ã§æŽæ°ãããããŒã¿ã®è¡šç€ºã«Socket.ioã¯æé©ã§ããããŒã¿ã®å³ææ§ãæ±ããããã¢ããªã±ãŒã·ã§ã³ã«ãããŠãSocket.ioã¯åŒ·åãªããŒã«ãšãªããŸãã
ãªã³ã©ã€ã³ã²ãŒã
ãªã³ã©ã€ã³ã²ãŒã ã§ã¯ããã¬ã€ã€ãŒéã®ãªã¢ã«ã¿ã€ã éä¿¡ãäžå¯æ¬ ã§ããSocket.ioã¯ãã²ãŒã ã®ç¶æ ããã¬ã€ã€ãŒã®ã¢ã¯ã·ã§ã³ããªã¢ã«ã¿ã€ã ã§åæãããããã«äœ¿çšãããŸãã
ã³ã©ãã¬ãŒã·ã§ã³ããŒã«
å ±åç·šéããããªäŒè°ãªã©ã®ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ã«ãSocket.ioãå©çšãããŠããŸãããŠãŒã¶ãŒéã®ãªã¢ã«ã¿ã€ã ãªããåããæ¯æŽããå¹ççãªå ±åäœæ¥ãå¯èœã«ããŸãã
IoTããã€ã¹ãšã®é£æº
IoTããã€ã¹ããã®ããŒã¿åéãå¶åŸ¡ã«ãSocket.ioã䜿çšãããŸãããªã¢ã«ã¿ã€ã ã§ããã€ã¹ã®ç¶æ ãç£èŠããå¶åŸ¡ããããã®ã€ã³ãã©ã¹ãã©ã¯ãã£ãšããŠé©ããŠããŸãã
ä»åŸã®å±æãšçºå±å¯èœæ§
Socket.ioã®æªæ¥ã¯éåžžã«æããã§ãã以äžã«ãä»åŸã®å±æãšçºå±å¯èœæ§ã瀺ããŸãã
5GãšIoTã®æ®å
5Gãããã¯ãŒã¯ã®æ®åã«äŒŽããããé«éã§å®å®ããéä¿¡ãå¯èœã«ãªããŸããããã«ãããSocket.ioãå©çšãããªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ã®éèŠãããã«é«ãŸãã§ãããããŸããIoTããã€ã¹ã®å¢å ã«ããããªã¢ã«ã¿ã€ã éä¿¡ã®éèŠæ§ãå¢ããŠãããŸãã
WebRTCãšã®é£æº
WebRTCïŒWeb Real-Time CommunicationïŒãšã®é£æºã«ããããããªäŒè°ãP2Péä¿¡ãªã©ãããé«åºŠãªãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³ã®éçºãå¯èœã«ãªããŸããSocket.ioã¯ãã·ã°ããªã³ã°ã®åœ¹å²ãæãããWebRTCã®éä¿¡ãè£å®ããããšãæåŸ ãããŸãã
ãªãŒãã³ãœãŒã¹ã³ãã¥ããã£ã®æ¡å€§
Socket.ioã¯ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãããã³ãã¥ããã£ã«ããç¶ç¶çãªéçºãšæ¹åãè¡ãããŠããŸããæ°æ©èœã®è¿œå ããã°ä¿®æ£ãè¿ éã«è¡ããããããä»åŸãé²åãç¶ããã§ãããã
ãããªãåŠç¿ãªãœãŒã¹
Socket.ioã«ã€ããŠããã«åŠã³ããå Žåã以äžã®ãªãœãŒã¹ã掻çšãããšè¯ãã§ãããã
å ¬åŒããã¥ã¡ã³ã
Socket.ioã®å ¬åŒããã¥ã¡ã³ãã¯ãAPIã®è©³çŽ°ãªèª¬æã䜿çšäŸãæäŸããŠããŸãããŸãã¯å ¬åŒããã¥ã¡ã³ããèªã¿èŸŒã¿ãåºæ¬çãªäœ¿ãæ¹ãç解ããŸãããã
ãªã³ã©ã€ã³ã³ãŒã¹
UdemyãCourseraãªã©ã®ãªã³ã©ã€ã³æè²ãã©ãããã©ãŒã ã«ã¯ãSocket.ioã®äœ¿ãæ¹ãåŠã¶ããã®ã³ãŒã¹ãå€æ°ãããŸãããããã®ã³ãŒã¹ãåè¬ããããšã§ãå®è·µçãªã¹ãã«ãç¿åŸã§ããŸãã
ããã°èšäºãšãã¥ãŒããªã¢ã«
ã€ã³ã¿ãŒãããäžã«ã¯ãå€ãã®Socket.ioã«é¢ããããã°èšäºããã¥ãŒããªã¢ã«ãååšããŸããå ·äœçãªå®è£ äŸãåé¡è§£æ±ºã®ãã³ããåŸãããã«ããããã®èšäºãåèã«ããããšãã§ããŸãã
GitHubãªããžããª
Socket.ioã䜿çšãããªãŒãã³ãœãŒã¹ãããžã§ã¯ãã®ãªããžããªãé²èŠ§ããã³ãŒããåèã«ããããšã§ãå®éã®ãããžã§ã¯ãã«ã©ã®ããã«é©çšãããŠããããåŠã¶ããšãã§ããŸããç¹ã«ã人æ°ã®ãããªããžããªã¯å€ãã®æçšãªæ å ±ãæäŸããŠãããŸãã