// server.js
const net = require('net')
const server = net.createServer()
const users = [];
server.on('connection', clientSocket => {
users.forEach(item => {
console.log(item.nickname);
})
// 接收到某一客户端信息
clientSocket.on('data', _data => {
const data = JSON.parse(_data.toString().trim())
// console.log(data, 'server');
switch (data.type) {
case types.login:
if (users.find(item => item.nickname === data.nickname)) {
return clientSocket.write(JSON.stringify({
type: types.login,
success: false,
message: '昵称已重复'
}))
}
clientSocket.nickname = data.nickname
users.push(clientSocket)
clientSocket.write(JSON.stringify({
type: types.login,
success: true,
message: '登录成功',
nickname: data.nickname,
sumUsers: users.length
}))
users.forEach(user => {
if (user !== clientSocket) {
user.write(JSON.stringify({
type: types.log,
message: `${data.nickname} 进入了聊天室, 当前在线用户: ${users.length}`
}))
}
})
break;
case types.broadcast: // 群聊
users.forEach(item => {
item.write(JSON.stringify({
type: types.broadcast,
nickname: clientSocket.nickname,
message: data.message
}))
})
break;
case types.p2p: // 私聊
const find = users.find(item => item.nickname === data.nickname)
if (!find) {
return clientSocket.write(JSON.stringify({
type: types.p2p,
success: false,
message: '该用户不存在'
}))
}
find.write(JSON.stringify({
type: types.p2p,
success: true,
nickname: clientSocket.nickname,
message: data.message
}))
break;
default:
break;
}
})
// 监听终端结束
clientSocket.on('end', () => {
// 移除下线用户
const index = users.findIndex(item => item.nickname === clientSocket.nickname)
const offlineUser = users[index]
if (index !== -1) {
users.splice(index, 1)
// 广播通知离线
users.forEach(user => {
user.write(JSON.stringify({
type: types.log,
message: `${offlineUser.nickname}离线`
}))
})
}
})
})
server.listen(3000, () => console.log('server running'))
const types = {
login: 0,
broadcast: 1,
p2p: 2,
log: 3
}
// client.js
const net = require('net')
const client = net.createConnection({host: '127.0.0.1', port: 3000})
let nickname = ''
client.on('connect', () => {
process.stdout.write('请输入昵称: ')
process.stdin.on('data', _data => {
const data = _data.toString().trim()
if (!nickname) {
return client.write(JSON.stringify({
type: types.login,
nickname: data
}))
}
const matches = /^@(\w+)\s(.+)$/.exec(data)
if (matches) {
return client.write(JSON.stringify({
type: types.p2p,
nickname: matches[1],
message: matches[2]
}))
}
client.write(JSON.stringify({
type: types.broadcast,
message: data
}))
})
})
client.on('data', _data => {
const data = JSON.parse(_data.toString().trim())
switch (data.type) {
case types.login:
if (!data.success) {
console.log(`登录失败: ${data.message}`);
process.stdout.write('请重新输入昵称: ')
} else {
console.log(`登录成功,当前在线人数: ${data.sumUsers}`);
nickname = data.nickname
}
break;
case types.broadcast:
console.log(`${data.nickname}: ${data.message}`);
break;
case types.p2p:
if (!data.success) {
return console.log(`发送失败: ${data.message}`)
}
console.log(`${data.nickname} 对你说: ${data.message}`);
break;
case types.log:
console.log(`${data.message}`);
break;
default:
break;
}
})
const types = {
login: 0,
broadcast: 1,
p2p: 2,
log: 3
}