webSocket 即时刷新页面消息
http协议它有局限性,服务器不能单方面向客户端发送消息
在以往的开发中,这种想即时通讯,用的都是轮询 以及长连接
webSocket 它的优势就是服务端推送消息
话不多说先上代码
代码内各行功能性代码都有注释
/*
服务端代码
*/
const ws = require('ws'); // 引入ws模块
// 创建ws服务器,并设置端口号为9000
let wsServer = new ws.Server({
port: 9000
})
// 监听客户端的接入
wsServer.on('connection', connection);
// 客户端接入的事件处理函数
function connection(socket) {
// 监听客户端发送消息
socket.on('message', msg => {
let data = JSON.parse(msg)
//判断接受消息的类型
switch (data.type) {
case 'login': //新用户加入
socket.nickname = data.username //保存用户名属性
broadcast(
//发送json字符串告诉客户端有新用户加入
JSON.stringify({
username: data.username,// 用户的名字
time: getTime(), // 发表的时间
type: data.type // 类型
})
)
break
case 'msg':
//发送json字符串告诉客户端有新用户加入
broadcast(
JSON.stringify({
username: data.username, // 用户的名字
time: getTime(), // 发表的时间
message: data.message, //用户发表的内容
type: data.type // 类型
})
)
break
}
})
//监听错误信息
socket.on('error', (err) => {
console.log(err)
})
//监听断开连接
socket.on('close', () => {
broadcast(
JSON.stringify({
username: socket.nickname, // 用户的名字
time: getTime(), // 离开的时间
type: 'leave' // 离开的类型
})
)
})
}
//给所有连接的客户端发送消息
function broadcast(str) {
//遍历所有连接的客户端
wsServer.clients.forEach((conn) => {
//发送消息
conn.send(str)
})
}
function getTime() {
var date = new Date();
var hour = date.getHours();
var min = date.getMinutes()
var sec = date.getSeconds()
min = min < 10 ? "0" + min : min
sec = sec < 10 ? "0" + sec : sec
return hour + ":" + min + ":" + sec
}
/*
客户端代码
*/
//获取button对象
let addBtn = document.getElementById("addBtn") // 加入按钮
let sendBtn = document.getElementById("sendBtn") // 发送按钮
let username = document.getElementById("username") // 用户名
var message = document.getElementById("message") // 发送的内容
//定义全局
let ws = null;
// 点击添加新用户
addBtn.onclick = function () {
//调用join函数 创建跟后台的链接
join()
}
//给用户名文本框添加键盘点击事件
username.onkeyup = function (e) {
//如果输入的是回车,进聊天室
if (e.keyCode === 13) {
//调用join函数 创建跟后台的链接
join()
//禁止如数文本内容
username.disabled = true
}
}
// 点击发送内容按钮
sendBtn.onclick = function () {
sendMessage()
}
//给发送内容文本框 添加键盘事件
message.onkeyup = function (e) {
// keyCode 13 就是回车键
if (e.keyCode === 13 && !sendBtn.disabled) {
sendMessage()
}
}
function join() {
addBtn.disabled = true //禁止添加新用户按钮
username.disabled = true //禁止如数文本内容
sendBtn.disabled = false //给改变发送内容文本框可以编辑
// 创建WebSocket对象,WebSocket使用的是ws协议
ws = new WebSocket('ws://localhost:9000') // localhost就是你起服务的主机IP
ws.onopen = function () {
//获取用户名
let username = document.getElementById("username").value
// 向服务器端发送消息
ws.send(
// 往后台发送json字符串
JSON.stringify({
username: username,
type: 'login' //添加的对象
})
)
}
// onmessage与ws已经绑定,接受消息回来的时候还是会回到这里来
// 服务器发送消息后会触发
ws.onmessage = function (e) {
console.log(e.data)
//字符串对象转json对象
let data = JSON.parse(e.data)
let show
switch (data.type) {
case 'login': //新用户
show = `<span class="enter">${data.username}</span>加入了房间`
break;
case 'msg': // 有新的聊天信息
show = `<span class="talk">${data.username}</span> ${data.time} <div>${data.message}</div>`
break
case 'leave': //有人离开聊天室
show = `<span class="leave">${data.username}</span>离开了房间 ${data.time}`
break;
}
//创建 里元素节点
let li = document.createElement("li")
li.innerHTML = show
document.getElementById("msg").append(li)
}
}
function sendMessage() {
// 用户名
let username = document.getElementById("username").value
// 发送内容
let msg = document.getElementById("message").value
//发送聊天消息给服务器
ws.send(JSON.stringify({
username: username,
message: msg,
type: 'msg'
}))
// 发送内容置空
document.getElementById("message").value = ''
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.enter{
color:lightgreen;
}
.talk{
color: dodgerblue;
}
.leave{
color: red;
}
</style>
</head>
<body>
<div id="main">
<p>
<input type="text" id="username" placeholder="请输入用户名" />
<button type="button" id="addBtn">加入</button>
</p>
<p>
<input type="text" id="message" placeholder="请输入聊天信息" />
<button type="button" id="sendBtn" disabled>发送</button>
</p>
<ul id="msg"></ul>
</div>
<script src="./js/index.js"></script>
</body>
</html>