ショコラ
Node.jsでチャットを作るには?
Node.js のチャットプログラムを もっさん流 にアレンジしてみました。
もっさん先輩
- express をインストールします。
npm install express
- socket.io をインストールします。
npm install socket.io
- dayjs をインストールします。
npm install dayjs
- パッケージを import で読み込みたいので、package.json に「”type”: “module”,」を追加します。
{
"type": "module",
"dependencies": {
"dayjs": "^1.11.7",
"express": "^4.18.2",
"socket.io": "^4.5.4"
}
}
- チャットサーバープログラム
import express from 'express'
import http from 'http'
import {Server} from 'socket.io'
import dayjs from 'dayjs'
const app = express(),
server = http.createServer(app),
io = new Server(server),
msg = (name,message) => ({date:dayjs().format('MM月DD日 HH時mm分'),name,message})
app.use(express.static('public'))
server.listen(80)
io.sockets.on('connection',socket => {
socket.on('enter',name => socket.aaa = name)
socket.on('post',message => io.sockets.emit('message',msg(socket.aaa,message)))
socket.on('disconnect',() => io.sockets.emit('message',msg(socket.aaa,'退出しました。')))
})
↑プログラムは数行です。この短さは驚異的です。
- チャットクライアントプログラム
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>chat</title>
<script src="https://code.jquery.com/jquery-3.6.2.slim.min.js" integrity="sha256-E3P3OaTZH+HlEM7f1gdAT3lHAn4nWBZXuYe89DFg2d0=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.js"></script>
</head>
<body>
<div class="ui main container">
<div class="ui feed"></div>
<div class="ui form">
<div class="field">
<label>名前</label>
<input id="name" readonly="true">
</div>
<div class="field">
<label>メッセージ</label>
<textarea id="message" placeholder="メッセージ" rows="2"></textarea>
</div>
<button id="send" class="ui blue labeled submit icon button">
<i class="icon paper plane outline"></i>メッセージ送信
</button>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io.connect()
// メッセージ受信
socket.on('message',({date,name,message}) => {
const el = document.createElement('p')
const items = ['astronaut_tone1','baby_chick','bug']
let n = name.length % items.length
el.innerHTML = `
<div class="event">
<div class="label">
<em data-emoji=":${items[n]}:" class="medium"></em>
</div>
<div class="content">
<div class="user">${name}</div>
<div class="date">${date}</div>
<div class="summary">${message}</div>
</div>
</div>`
document.querySelector('.feed').prepend(el.firstElementChild)
})
// 入室
const name = prompt('名前をご入力ください。')
document.querySelector('#name').value = name
socket.emit('enter',name)
socket.emit('post','入室しました。')
// 送信ボタン
document.querySelector('#send').addEventListener('click',() => {
const message = document.querySelector('#message')
if ('' !== message.value) {
socket.emit('post',message.value)
message.value = ''
}
})
</script>
</body>
</html>
以上