首先我们保证已经安装了nodejs
先上一张效果图
建一个文件夹 ws_nodeserver,在里面建一个server.js ,然后在ws_websocket文件夹下执行 npm init 一直敲回车 生成package.json文件。
目录结构为
下载我们引用的依赖 cnpm install --save ws
server.js中引入并创建一个ws
var WebSocketServer = require('ws').Server;
wss = new WebSocketServer({ port: 8181 });
wss.on('connection', function (ws,req) {
//接收client发的消息
ws.on('message', function (message) {
console.log('接收到来自clent的消息:'+message)
});
ws.on('close',function(e){
console.log('长连接已关闭')
})
})
好嘞,这样一个websocket服务就建好了。
然后前端代码:
ws_conect() {
var ws = new WebSocket("ws://localhost:8181");
ws.onopen = function(e) {
console.log("链接上了ws");
};
ws.onmessage = this.ws_onmessage;
ws.onclose = this.ws_close;
},
ws_onmessage(e){
var data = JSON.parse(e.data);
console.log("我client收到消息了:" + e.data);
},
ws_close(e){
}
好,这样就可以连上websocket了。
但是我们要的是可以两个人聊天的工具这么做是不够的,接下来我们慢慢完善。
说一下思路,两个人聊天首先要区分的是两个人的身份,就是我服务端要知道接收的是谁的消息,并且要退送给谁。这时候就得在连长连接的时候告诉服务端你是谁。然后服务端这边得将连接到ws的人记录下来,也就是在线的人,然后在推送的时候在里面找出来进行推送。
话不多说直接上代码 server.js
var WebSocketServer = require('ws').Server;
var qs = require('qs');
var _ = require('lodash');
wss = new WebSocketServer({ port: 8181 });
var wsObj = {};
var nameArr = [];//记录登录用户的id
wss.on('connection', function (ws,req) {
//通过连接地址上的id区分开用户
let url = req.url;
let prarms = qs.parse(_.split(url,'?')[1]); // token=xxxxxx
//判断此用户有没有连过长连接,如果连过断开重新连
if(wsObj[prarms.id]){
wsObj[prarms.id].close();
delete wsObj[prarms.id];
nameArr.map((item,index) =>{
if(item == prarms.id){
nameArr.splice(index,1)
}
})
}else{
nameArr.push(prarms.id);
}
// 连上之后,将在线用户发给用户
var online_obj = {
code:200,
online_user:nameArr
}
//每个用户一个ws,记录在对象身上,以便于推送的时候好查找
wsObj[prarms.id] = ws;
//
for(var i in wsObj){
wsObj[i].send(JSON.stringify(online_obj))
}
//接收client发的消息
ws.on('message', function (message) {
var res = JSON.parse(message);
//给用户发消息获取,告诉他谁的消息
var obj = {
code:202,
msg:res.text,
name:res.token
}
wsObj[res.token].send(JSON.stringify(obj));
});
ws.on('close',function(e){
console.log('长连接已关闭')
})
});
前端代码 user.vue
<template>
<div class="wrapper">
<el-button type="primary" icon="el-icon-chat-dot-round" @click="ws_conect">{{text}}</el-button>
<p>在线列表:</p>
<li class="userlist" v-for="(item , index) in online_list" :key="index" @click="chat_to(item,index)" :class="{active:i == index}">
{{item}}
</li>
<p v-if="touser">正在跟{{touser}}聊天</p>
<div class="msg_box">
<li v-for="(item,ind) in msg_list" :key="ind">
{{item.name}}:{{item.msg}}
</li>
</div>
<div v-show="input_">
<el-input style="width:400px;margin-top:20px;" type="textarea" :rows="2" placeholder="请输入聊天内容" v-model="textarea">
</el-input>
<el-button type="primary" icon="el-icon-chat-dot-square" @click="send_msg">发送</el-button>
</div>
</div>
</template>
<script>
export default {
components: {},
name: "mytree",
props: {
treeList: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
i: -1,
load: false,
text: "发起链接",
msg_list: [], //获取到的消息
textarea: "", //输入的内容
input_: true, //是否显示聊天框
touser: "", //要跟谁聊天
ws: {},
time_token: "123456", //链接时的身份,固定不变
online_list: [], //在线列表
name: ""
};
},
watch: {},
computed: {},
methods: {
chat_to(token, i) {
if (token != this.time_token) {
this.touser = token;
this.input_ = true;
this.i = i;
}
},
send_msg() {
var obj = {
token: this.touser,
name: "小红",
text: this.textarea
};
this.ws.send(JSON.stringify(obj));
var msg = {
name: obj.token,
msg: this.textarea
};
this.msg_list.push(msg);
},
ws_conect() {
var ws = new WebSocket("ws://localhost:8181?id=" + this.time_token);
this.ws = ws;
ws.onopen = function(e) {
console.log("Connection to server opened");
};
ws.onmessage = this.ws_onmessage;
ws.onclose = this.ws_close;
},
ws_onmessage(e) {
var data = JSON.parse(e.data);
if (data.code == 200) {
this.online_list = data.online_user;
} else if (data.code == 202) {
this.msg_list.push(data);
}
console.log("我client收到消息了:" + e.data);
},
ws_close(e) {}
},
created() {},
mounted() {}
};
</script>
<style lang="scss" scoped>
.wrapper {
.userlist {
margin-top: 20px;
cursor: pointer;
}
.msg_box {
width: 500px;
height: 400px;
border: 1px solid #409eff;
background: #fff;
}
.active {
background: #409eff;
color: #fff;
}
}
</style>
然后在别的项目里面在放入这段代码 两个页面就可以聊天了
注意 里面有个time_token
这个是用来区分用户的,所以在别的地方用的时候注意修改成其他的,不要一样。
在项目中用的话 这个是登录的时候获取的,每个用户一个,我是在这里写死了