准备工作
webSocket 需要有服务器支持,所以这个demo使用了简单的 nodejs 服务,因此想要运行这个demo,需要有node 环境
nodejs 下载地址
代码编写
1.服务端代码(我会在后边放出完整项目,这一步可跳过)
- 新建项目,内部新建 server.js文件(使用了 express框架,还需要下载webSocket 依赖,)
const express = require("express");
const app = express();
app.use(express.static("www"));
const http = require("http");
const urlib = require("url");
const server = http.createServer(app);
const WebSocket = require("ws");
// 创建webSocket服务器对象,参数可以填写一个http服务器对象进行绑定。
const wss = new WebSocket.Server({ server })
// 使用一个数组记录所有用户的连接对象
let users = [];
// wss对象的 on connection事件,当有客户端连接成功时候触发,事件函数的参数ws就是这个用户的连接对象。
wss.on("connection", function (ws, req) {
console.log("有一个新用户连接了");
let urlQuery=urlib.parse(req.url,true);
console.log(urlQuery.query.nickname)
ws.nickname = urlQuery.query.nickname;
console.log(ws.nickname + "连接了");
users.push(ws);
sendMsg({
type: "user-enter",
user: ws.nickname
})
ws.on("close", function () {
console.log(ws.nickname + "断开连接");
users.splice(users.indexOf(ws), 1);
sendMsg({
type: "user-leve",
user: ws.nickname
})
});
ws.on("message", function (m) {
let data = JSON.parse(m);
switch (data.type) {
case "group-msg":
data.from = ws.nickname;
sendMsg(data);
return;
}
})
})
function sendMsg(data) {
users.forEach(ws => {
ws.send(JSON.stringify(data));
});
}
server.listen(3000, function () {
console.log('server runing');
})
2.编写客户端html代码
<!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>
#main {
display: flex;
}
#left {
width: 70%;
}
#right {
flex-grow: 1;
}
#msg-box {
width: 100%;
height: 600px;
border: 1px solid black;
}
#input-line {
margin-top: 10px;
display: flex;
}
#msg-input {
flex-grow: 1;
}
.enter {
color: chartreuse;
}
.leave {
color: red;
}
</style>
</head>
<body>
<div id="main">
<div id="left">
<h1>欢迎来到聊天室</h1>
<div>
<input id="nickname-input" placeholder="请输入您的昵称" type="text">
<button id="login-btn">登录</button>
</div>
<div id="msg-box">
</div>
<div id="input-line">
<input id="msg-input" placeholder="请输入聊天内容" type="text">
<button id="send-btn">发送</button>
</div>
</div>
<div id="right">
</div>
</div>
</body>
<script>
const nicknameInput = document.getElementById("nickname-input");
const loginBtn = document.getElementById("login-btn");
const msgBox = document.getElementById("msg-box");
const msgInput = document.getElementById("msg-input");
const sendBtn = document.getElementById("send-btn");
// webSocket连接对象。
let ws = null;
loginBtn.onclick = function () {
if (ws) {
alert("已经登录,无法再次登录");
return;
}
if (!nicknameInput.value.trim()) {
alert("昵称不能为空");
return;
}
// 通过创建webSocket对象进行webSocket连接。参数是连接地址。
ws = new WebSocket("ws://127.0.0.1:3000?nickname=" + nicknameInput.value.trim());
// onopen事件,当连接成功时触发。
ws.onopen = function () {
console.log("连接成功了");
alert("登录成功");
};
ws.onclose = function () {
ws = null;
console.log("连接断开了");
}
ws.onerror = function () {
ws = null;
}
ws.onmessage = function (e) {
let data = JSON.parse(e.data);
switch (data.type) {
case "group-msg":
receiveGroupMsg(data);
break;
case "user-enter":
userEnter(data);
break;
case "user-leave":
userLeave(data);
break;
default:
break;
}
}
}
// 收到群发消息
function receiveGroupMsg(data) {
let p = document.createElement("p");
let s1 = document.createElement("span");
s1.classList.add("from");
let s2 = document.createElement("span");
s1.textContent = data.from;
s2.textContent = ":" + data.content;
p.appendChild(s1);
p.appendChild(s2);
insertParagraph(p);
}
// 收到系统消息
function userEnter(data) {
let p = document.createElement("p");
let s1 = document.createElement("span");
s1.classList.add("from");
let s2 = document.createElement("span");
s2.classList.add("enter")
s1.textContent = data.user;
s2.textContent = "加入了群聊";
p.appendChild(s1);
p.appendChild(s2);
insertParagraph(p);
}
function userLeave(data) {
let p = document.createElement("p");
let s1 = document.createElement("span");
s1.classList.add("from");
let s2 = document.createElement("span");
s2.classList.add("leave")
s1.textContent = data.user;
s2.textContent = "离开了群聊";
p.appendChild(s1);
p.appendChild(s2);
insertParagraph(p);
}
function insertParagraph(p) {
if (msgBox.scrollTop == msgBox.scrollHeight - msgBox.clientHeight) {
msgBox.appendChild(p);
msgBox.scrollTop = msgBox.scrollHeight - msgBox.clientHeight;
} else {
msgBox.appendChild(p);
}
}
sendBtn.onclick = sendMsg;
msgInput.onkeydown = function (e) {
if (e.keyCode == 13) {
sendMsg();
}
}
function sendMsg() {
if (!ws) {
alert("请先登录");
return;
}
if (!msgInput.value.trim()) {
alert("发送内容不能为空");
return;
}
let data = {
type: "group-msg",
content: msgInput.value.trim()
}
// ws.send,向对方发送消息,参数只能是buffer或字符串。
ws.send(JSON.stringify(data));
msgInput.value = "";
}
</script>
</html>
运行
webSocket