建立專案
cd Desktop/WebRTC/sample
mkdir socketio-chartroom
cd socketio-chartroom
touch server.js
npm init --yes
npm install express socket.io
產生本地端開發用SSL憑證
mkcert -install
mkcert 0.0.0.0 localhost 127.0.0.1 ::1
mv 0.0.0.0+3-key.pem key.pem & mv 0.0.0.0+3.pem cert.pem
在 server.js 加入以下程式碼
'use strict'
const https = require('https')
const fs = require('fs')
const express = require('express')
const socketIo = require('socket.io')
const app = express()
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
}
const https_server = https.createServer(options, app)
https_server.listen(4443, '0.0.0.0')
const io = socketIo(https_server, {
cors: true,
})
// 收到使用者連線
io.sockets.on('connection', (socket) => {
console.log(socket.id, '已連線')
socket.on('message', (room, data) => {
io.in(room).emit('message', room, data)
})
socket.on('join', (room) => {
socket.join(room)
socket.emit('joined', room, socket.id)
})
socket.on('leave', (room) => {
socket.leave(room)
socket.to(room).emit('bye', room, socket.id)
socket.emit('leave', room, socket.id)
})
})
在專案內新增一個 client
資料夾及以下結構
client
├── index.html
└── js
└── client.js
在 index.html
中加入
<html>
<head>
<title>Chat Room</title>
</head>
<body>
<table align="center">
<h1 style="text-align: center">聊天室</h1>
<tr>
<td>
<label for="username">UserName: </label>
<input type="text" id="username" />
</td>
</tr>
<tr>
<td>
<label for="room">room: </label><input type="text" id="room" />
<button id="connect">Connect</button>
<button id="leave" disabled>Leave</button>
</td>
</tr>
<tr>
<td>
<label for="output">Content: </label><br />
<textarea disabled style="line-height: 1.5" id="output" rows="10" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<label for="input">Input: </label><br />
<textarea disabled id="input" rows="3" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<button id="send">Send</button>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
<script src="./js/client.js"></script>
</body>
</html>
在 client.js
中加入
'use strict'
const userName = document.querySelector('input#username')
const inputRoom = document.querySelector('input#room')
const btnConnect = document.querySelector('button#connect')
const btnLeave = document.querySelector('button#leave')
const outputArea = document.querySelector('textarea#output')
const inputArea = document.querySelector('textarea#input')
const btnSend = document.querySelector('button#send')
let socket
let room
btnConnect.onclick = () => {
socket = io('wss://localhost:4443')
socket.on('joined', (room, id) => {
btnConnect.disabled = true
btnLeave.disabled = false
inputArea.disabled = false
btnSend.disabled = false
})
socket.on('leave', (room, id) => {
btnConnect.disabled = false
btnLeave.disabled = true
inputArea.disabled = true
btnSend.disabled = true
socket.disconnect()
})
socket.on('message', (room, data) => {
console.log(room, data)
outputArea.scrollTop = outputArea.scrollHeight
outputArea.value = outputArea.value + data + '\n'
})
socket.on('disconnect', (reason) => {
btnConnect.disabled = false
btnLeave.disabled = true
inputArea.disabled = true
btnSend.disabled = true
})
room = inputRoom.value
socket.emit('join', room)
}
btnSend.onclick = () => {
let data = inputArea.value
data = userName.value + ':' + data
socket.emit('message', room, data)
inputArea.value = ''
}
btnLeave.onclick = () => {
room = inputRoom.value
socket.emit('leave', room)
}
inputArea.onkeypress = (event) => {
if (event.keyCode === 13) {
let data = inputArea.value
data = userName.value + ':' + data
socket.emit('message', room, data)
inputArea.value = ''
event.preventDefault()
}
}
啟動 server
開啟終端機,cd 進入專案,執行 node server.js
啟動使用者端
開啟另一個終端機,cd 進入專案的 client 資料夾內,執行
http-server -S -C ../cert.pem -K ../key.pem -o