Socket.IO サンプルコード(2)~簡易チャットアプリ~
このコードはroomを使う例である。
Socket.IOを使用する場合には、HTTPサーバーを立ててSocket.IOを統合する必要がある。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Socket.IO サンプルコード(2)~簡易チャットアプリ~</title>
</head>
<body>
<h1>Socket.IO サンプルコード(2)~簡易チャットアプリ~</h1>
http://192.168.2.100:3000/?code=100a
<br>
code=100aのようにクエリを付けてアクセスすること
クエリは重複しないものとする。
<div>
<input type="text" id="handlename" placeholder="名前">
</div>
<div>
<input type="text" id="roomInput" placeholder="ルーム名">
<button onclick="joinRoom()">ルームに参加</button>
</div>
<div>
<input type="text" id="messageInput" placeholder="メッセージ">
<button onclick="sendMessage()">送信</button>
</div>
<ul id="messageList"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Socket.IO サンプルコード(2)~超簡易チャットアプリ~</title>
</head>
<body>
<h1>Socket.IO サンプルコード(2)~超簡易チャットアプリ~</h1>
http://192.168.2.100:3000/?code=100a
<br>
code=100aのようにクエリを付けてアクセスすること
クエリは重複しないものとする。
<div>
<input type="text" id="handlename" placeholder="名前">
</div>
<div>
<input type="text" id="roomInput" placeholder="ルーム名">
<button onclick="joinRoom()">ルームに参加</button>
</div>
<div>
<input type="text" id="messageInput" placeholder="メッセージ">
<button onclick="sendMessage()">送信</button>
</div>
<ul id="messageList"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
// keyがsocketID,値がcode
let socketID_code_c = new Map();
// keyがcode,値がroom
let code_room_c = new Map();
// keyがcode,値がhandlename
let code_handlename_c = new Map();
const socket = io();
// ルームに参加
function joinRoom() {
let handlename = document.getElementById('handlename').value;
handlename = handlename === '' ? '名無しさん' : handlename;
let room = document.getElementById('roomInput').value;
const searchParams = new URLSearchParams(location.search);
const code = searchParams.get("code");
if (searchParams !== null && code !== null && room !== '') {
// サーチ情報のそれぞれのキーに対応する値を、
// URLSearchParamsオブジェクトのget()メソッドを使用して取得可能である。
console.log("code = " + searchParams.get("code")); // URLUtils.searchParams
socket.emit('joinRoom', {
room,
code,
handlename
});
}
}
// メッセージを送信
function sendMessage() {
const room = document.getElementById('roomInput').value;
const searchParams = new URLSearchParams(location.search);
let code = searchParams.get("code");
if (searchParams !== null && code !== null) {
const room = document.getElementById('roomInput').value;
const message = document.getElementById('messageInput').value;
socket.emit('sendMessage', {
room,
message,
code
});
}
}
// メッセージを受信
socket.on('receiveMessage', (data) => {
const messageList = document.getElementById('messageList');
// 新しいli要素を作成する。li要素はメッセージをリストアイテムとして表示するために使用される。
const li = document.createElement('li');
const {
message,
code,
socketID
} = data
console.log(message + " " + code);
console.log("socketID_code_c.get(" + socketID + ") = " + socketID_code_c.get(socketID));
console.log("code_room_c.get(" + code + ") = " + code_room_c.get(code));
console.log("code_handlename_c.get(" + code + ") = " + code_handlename_c.get(code));
li.innerHTML = code_handlename_c.get(code) + "@chat\n<br>" + message;
messageList.appendChild(li);
});
// socketID等を受信
socket.on('receive_socketID', (data) => {
console.log(data);
const {
socketID,
room,
code,
handlename,
socketID_codeObject,
code_roomObject,
code_handlenameObject
} = data;
console.log("socketID = " + socketID);
console.log("code = " + code);
console.log("room = " + room);
code_handlename_c = new Map(Object.entries(code_handlenameObject));
code_room_c = new Map(Object.entries(code_roomObject));
socketID_code_c = new Map(Object.entries(socketID_codeObject));
console.log("code_handlename_c = " + code_handlename_c.get(code));
console.log("code_room_c = " + code_room_c.get(code));
console.log("socketID_code_c = " + socketID_code_c.get(socketID));
});
</script>
</body>
</html>
server_http.js
const hostname = '192.168.2.100';
const port = 3000;
const http = require('http');
const socketIO = require('socket.io');
const fs = require('fs');
const server = http.createServer((req, res) => {
fs.readFile('./index.html', 'utf-8', (error, data) => {
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf-8'
});
res.write(data);
res.end();
})
});
const io = require('socket.io')(server, {});
// サーバーの起動
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
// keyがsocketID,valueがcode
let socketID_code = new Map();
// keyがcode,valueがroom
let code_room = new Map();
// keyがcode,valueがhandlename
let code_handlename = new Map();
// 接続時の処理
io.on('connection', (socket) => {
console.log(`クライアントのID: ${socket.id} が接続しました。`);
// ルームへの参加
socket.on('joinRoom', (data) => {
const {
room,
code,
handlename
} = data;
socket.join(room);
console.log(`クライアントのID: ${socket.id}, code = ${code}, クライアントがルーム ${room} に参加しました。`);
const socketID = socket.id;
socketID_code.set(socketID, code);
code_room.set(code, room);
code_handlename.set(code, handlename);
const socketID_codeObject = Object.fromEntries(socketID_code.entries());
const code_roomObject = Object.fromEntries(code_room.entries());
const code_handlenameObject = Object.fromEntries(code_handlename.entries());
io.to(room).emit('receive_socketID', {
socketID,
room,
code,
handlename,
socketID_codeObject,
code_roomObject,
code_handlenameObject
}); // 同じルームのクライアントにメッセージを送信
});
// メッセージの送信
socket.on('sendMessage', (data) => {
const {
room,
message,
code
} = data;
const socketID = socket.id;
console.log(`code = ${code}, クライアントからのメッセージ(ルーム ${room}): ${message}`);
// 同じルームのクライアントにメッセージを送信 方法(1)
//io.to(room).emit('receiveMessage', message);
// 同じルームのクライアントにメッセージを送信 方法(2) ここから
// ルーム内のクライアントのIDリストを取得
// clientsはmapオブジェクト風のオブジェクト
const clients = io.sockets.adapter.rooms.get(room);
console.log(`room = ${room}, clients.size = ${clients.size}`);
if (clients) {
clients.forEach(clientId => {
console.log(`${room} クライアントのID: clientId = ${clientId}, code = ${socketID_code.get(clientId)}`)
// 各クライアントに個別にメッセージを送信
io.to(clientId).emit('receiveMessage', {
message,
code,
socketID
});
});
}
// 同じルームのクライアントにメッセージを送信 方法(2) ここまで
});
// 切断時の処理
socket.on('disconnect', () => {
console.log(`クライアントが切断しました。${socket.id}`);
});
});