pc端效果图
在这里插入图片描述
h5效果图
socket.vue文件
<template>
<div class="chat-box">
<header style="z-index: 99;">聊天室人数:{
{
count }}</header>
<!-- <van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="default">默认按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button> -->
<div class="msg-box" ref="msg-box">
<div
v-for="(i, index) in list"
:key="index"
class="msg"
:style="i.userId == userId ? 'flex-direction:row-reverse' : ''"
>
<div>
<!-- 用户头像 -->
<div class="user-head" @click="clickUser(i)">
<div
class="head"
:style="
` background: hsl(${
getUserHead(
i.userId,
'bck'
)}, 88%, 62%); clip-path:polygon(${
getUserHead(
i.userId,
'polygon'
)}% 0,100% 100%,0% 100%); transform: rotate(${
getUserHead(
i.userId,
'rotate'
)}deg)`
"
>
飞
</div>
</div>
<!-- 用户昵称 -->
<div class="user-name">
{
{
i.userId | filterNumber }}
</div>
<!-- 用户个人信息 -->
</div>
<!-- 显示的聊天信息部分 -->
<div class="user-msg">
<div
:style="i.userId == userId ? ' float: right;' : ''"
:class="i.userId == userId ? 'right' : 'left'"
>
<p class="user-msg-content">
<em
:class="i.userId == userId ? 'previewinRight' : 'previewinLeft'"
></em>
<span style="padding:5px"> {
{
i.content }}</span>
</p>
<p style="color:#ccc;font-size:10px">
{
{
new Date() | filterTime }}
</p>
</div>
</div>
</div>
</div>
<div class="input-box">
<input
type="text"
ref="sendMsg"
v-model="contentText"
@keyup.enter="sendText()"
/>
<div
class="btn"
:class="{ ['btn-active']: contentText }"
@click="sendText()"
>
发送
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
ws: null,
count: 0,
userId: null,
list: [],
contentText: "",
};
},
created() {
this.getUserID();
},
computed: {
u: function() {
return this.u.substring(3);
},
},
mounted() {
this.initWebSocket();
},
methods: {
clickUser(e) {
console.log("点击了", e);
},
getUserID() {
let time = new Date().getTime();
this.userId = time;
},
getUserHead(id, type) {
let ID = String(id);
if (type == "bck") {
return Number(ID.substring(ID.length - 3));
}
if (type == "polygon") {
return Number(ID.substring(ID.length - 2));
}
if (type == "rotate") {
return Number(ID.substring(ID.length - 3));
}
},
scrollBottm() {
let el = this.$refs["msg-box"];
el.scrollTop = el.scrollHeight;
},
sendText() {
let _this = this;
_this.$refs["sendMsg"].focus();
if (!_this.contentText) {
return;
}
let params = {
userId: _this.userId,
msg: _this.contentText,
};
_this.ws.send(JSON.stringify(params));
_this.contentText = "";
setTimeout(() => {
_this.scrollBottm();
}, 500);
},
initWebSocket() {
let _this = this;
if (window.WebSocket) {
let ws = new WebSocket("ws://192.168.11.76:8080");
_this.ws = ws;
ws.onopen = function() {
console.log("服务器连接成功");
};
ws.onclose = function() {
console.log("服务器连接关闭");
};
ws.onerror = function() {
console.log("服务器连接出错");
};
ws.onmessage = function(e) {
let resData = JSON.parse(e.data);
if (resData.funName == "userCount") {
_this.count = resData.users;
_this.list = resData.chat;
console.log(resData.chat);
} else {
_this.list = [
..._this.list,
{
userId: resData.userId, content: resData.msg },
];
}
};
}
},
},
};
</script>
<style lang="scss" scoped>
@import "@/style/mixin.scss";
.chat-box {
margin: 0 auto;
background: rgb(245, 244, 244);
position: absolute;
height: 100%;
width: 100%;
max-width: 700px;
box-sizing: border-box;
header {
position: fixed;
top: 0;
width: 100%;
height: 3rem;
background: #409eff;
max-width: 700px;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
font-size: 1rem;
}
.msg-box {
position: absolute;
height: calc(100% - 9rem);
width: 100%;
margin-top: 3rem;
overflow-y: scroll;
.msg {
width: 95%;
min-height: 2.5rem;
margin: 1.6rem 0.5rem;
position: relative;
display: flex;
justify-content: flex-start !important;
.user-head {
min-width: 2.5rem;
width: 20%;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background: #d48a8a;
display: flex;
justify-content: center;
align-items: center;
.head {
width: 1.2rem;
height: 1.2rem;
}
}
.user-head:hover {
cursor: pointer;
}
.user-name {
}
.user-msg {
width: 80%;
word-break: break-all;
position: relative;
z-index: 5;
.user-msg-content {
background-color: rgb(133, 219, 83);
z-index: 2;
padding: 0.7rem;
border-radius: 0.5rem;
margin-top: 0.2rem;
margin-bottom: 0.2rem;
margin-right: 25px;
font-size: 0.88rem;
margin-left: 10px;
}
.previewinLeft {
display: block;
border-width: 10px;
position: absolute;
font-size: 0;
line-height: 0;
left: -6px;
z-index: 10;
top: 3px;
border-style: solid dashed;
border-color: rgba(0, 0, 0, 0) rgb(133, 219, 83) rgba(0, 0, 0, 0)
rgba(0, 0, 0, 0);
z-index: 1;
}
.previewinRight {
display: block;
border-width: 10px;
position: absolute;
font-size: 0;
line-height: 0;
left: 101px;
top: 9px;
border-style: solid dashed dashed solid;
border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)
rgb(133, 219, 83);
z-index: 1;
}
.left {
animation: toLeft 0.5s ease both 1;
}
.right {
color: white;
animation: toright 0.5s ease both 1;
}
@keyframes toLeft {
0% {
opacity: 0;
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
@keyframes toright {
0% {
opacity: 0;
transform: translateX(10px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
}
}
}
.input-box {
padding: 1rem 0.5rem;
position: absolute;
z-index: 9;
bottom: -20px;
width: 97%;
height: 3.5rem;
background: #e7dfdf;
box-shadow: 0 0 5px #ccc;
display: flex;
justify-content: space-between;
align-items: center;
input {
height: 2.3rem;
display: inline-block;
width: 100%;
padding: 0.5rem;
border: none;
border-radius: 0.2rem;
font-size: 0.88rem;
}
.btn {
height: 2.3rem;
min-width: 4rem;
background: #9b9696;
padding: 0.5rem;
font-size: 0.88rem;
color: white;
text-align: center;
border-radius: 0.2rem;
margin-left: 0.5rem;
transition: 0.5s;
@include flex();
@include flexDir(column);
@include jusCon(center);
}
.btn-active {
background: #409eff;
}
}
}
</style>
服务器server.js文件
var userNum = 0;
var chatList = [];
var WebSocketServer = require('ws').Server;
wss = new WebSocketServer({
port: 8080
});
wss.broadcast = function (msg) {
wss.clients.forEach(function each(client) {
client.send(msg);
});
};
wss.on('connection', function (ws) {
userNum++;
wss.broadcast(JSON.stringify({
funName: 'userCount',
users: userNum,
chat: chatList
}));
console.log('Connected clients:', userNum);
ws.on('message', function (e) {
var resData = JSON.parse(e)
console.log('接收到来自clent的消息:' + resData.msg)
chatList.push({
userId: resData.userId,
content: resData.msg
});
wss.broadcast(JSON.stringify({
userId: resData.userId,
msg: resData.msg
}));
});
ws.on('close', function (e) {
userNum--;
wss.broadcast(JSON.stringify({
funName: 'userCount',
users: userNum,
chat: chatList
}));
console.log('Connected clients:', userNum);
console.log('长连接已关闭')
})
})
console.log('服务器创建成功,8080')