服务端 Link to heading
服务端是使用Node.js的ws模块,具体API可以点击这里 –> 点我查看 <–
// 引入express和ws
const express = require('express');
const app = express();
const WebSocket = require('ws');
// 使用express创建一个server
const serve = app.listen(3000,function () {
console.log('server run 3000');
});
// 把这个server绑定到websocket-server上
// 以后所有的请求都会经过websocket-server
// 如果是websocket连接就会由websocket-server接管,如果是普通连接会由express-server接管
const ws = new WebSocket.Server({
server: serve
});
// 这里创建的clientsInfo用来保存目前连接的所有用户发送的信息
// clientsUser用来保存连接的用户系统信息,采用自定义数据作为key,用来私发消息
let testData,clientsInfo = [],clientsUser = {};
app.get('/websocket/sendtoken', function(req, res){
console.log('data',req.query.token);
testData = req.query.token;
res.json({
msg: 'ok',
token: req.query.token
})
});
app.get('/websocket/clientsinfo', function(req, res){
res.json({
msg: 'ok',
data: clientsInfo
})
});
// 获取总连接个数
function allConnections(ws) {
let i = 0;
ws.clients.forEach(function each() {
i+=1
});
console.log(`[SERVER] : 共有${i}个连接`);
return i;
}
// 广播方法
ws.broadcast = function broadcast(data) {
let num = allConnections(ws);
ws.clients.forEach(function each(client) {
client.send('广播'+data +'共有'+ num +'个用户');
});
console.log(`[SERVER] 收到客户端消息: ${data},共有${num}个用户`);
}
// 删除用户方法
ws.removeClientInfo = function removeClientInfo(clientsInfo,client) {
let clientName = client.userName;
clientsInfo.forEach(function (item,index) {
if (item.userName === clientName){
clientsInfo.splice(index,1);
}
});
return clientsInfo;
}
ws.on('connection', function (result) {
console.log(`[SERVER] 客户端已连接`);
result.on('message', function (message) {
let res = JSON.parse(message);
if (res.used === 'login'){
// 用户登录后储存用户信息
clientsUser[res.userName] = result;
clientsInfo.push(res);
result.send('from server' + res.userName + '已储存');
console.log(res.userName + '已储存');
}
if(res.used === 'logout'){
// 用户登出时删除用户信息
delete clientsUser[res.userName];
ws.removeClientInfo(clientsInfo,res);
result.send('from server' + res.userName + '已删除');
console.log(res.userName + '已删除');
}
// 管理端查看 发送当前连接数
if(res.used === 'manage'){
let currentClients = JSON.stringify(clientsInfo);
result.send(currentClients);
console.log(res.userName + '信息已发送');
}
// 管理端给指定用户发送websocket信息
if (res.used === 'send'){
let sendUser = clientsUser[res.userName];
sendUser.send('hello,world!')
}
// 管理端 群发除了自己
if (res.used === 'sendall'){
console.log('接收到群发消息');
ws.clients.forEach(function each(client) {
if (client !== result) {
client.send('广播消息');
}
});
}
// 广播消息
// ws.broadcast(res.msg);
// console.log(`[SERVER] 收到客户端消息: ${res.msg}`);
// 单发消息
// result.send(`ECHO: ${res.msg}`, (err) => {
// if (err) {
// console.log(`[SERVER] error: ${err}`);
// }else {
// console.log(`[SERVER] 收到客户端消息: ${res.msg}`);
// }
// });
})
result.on('close', function (closeResult) {
console.log(`[SERVER] 客户端${closeResult}连接已关闭`);
});
});
客户端 Link to heading
客户端其实都一样,应为html5已经全面支持WebSocket技术,可以直接new出来了!!!
$(function () {
// 建立websocket连接
let ws = new WebSocket("ws://192.168.0.110:3000");
ws.getClientsInfo = function getClientsInfo() {
let WsData = JSON.stringify({
userName: 'manage',
token: 'manage_123456789',
used: 'manage'
});
// 发送消息
ws.send(WsData);
console.log('数据已经发送');
// 监听消息
ws.onmessage = function (evt){
let msg = JSON.parse(evt.data);
console.log(msg);
dataToHtml(msg);
$('.send').on('click',function (e) {
let rst = {
userName: e.target.dataset.username,
used: 'send'
};
console.log(rst);
ws.send(JSON.stringify(rst));
ws.onmessage = function (evt){
let msg = evt.data;
console.log(msg);
};
})
};
};
// 监听连接事件
ws.onopen = function () {
console.log('Web Socket 已连接');
ws.getClientsInfo();
}
// 群发
$('#sendAll').on('click',function () {
let msg = {
used: 'sendall'
}
ws.send(JSON.stringify(msg));
ws.onmessage = function (evt){
let msg = evt.data;
console.log(msg);
alert('群发成功')
};
})
function dataToHtml(data) {
let str = '';
data.forEach(function (item,index) {
str += `<div class="item flex-12 flex center-center">
<div class="flex-1 text-center">${index+1}</div>
<div class="flex-4 text-center">${item.userName}</div>
<div class="flex-4 text-center">${item.token}</div>
<div class="flex-1 text-center">${item.used}</div>
<div class="flex-2 text-center">
<button class="send" data-username="${item.userName}">发送</button>
</div>
</div>`
})
document.getElementById('itemGrounp').innerHTML = str;
}
})