使用的技术有
Vue.use(new VueSocketIO({ //进入当前页面时 注册socket
// debug: true, //开启调试
connection: 'ws://127.0.0.1:3001', //服务端地址
vuex: { //vuex存储
store,
actionPrefix: 'SOCKET_',
/*
在vuex的实例的 action 里面 这样
就会自动收到 服务端返回的数据
下面 就是在 mutation 里面同样配置
SOCKET_message:(state, data)=>{
console.log(data);
}
*/
mutationPrefix: 'SOCKET_',
options:{
//使用命名空间
useConnectionNamespace: true
}
}
}));
sockets:{
connect(){
// console.log("正在登录");
},
login(data){
//判断其是否登录成功
if (data.code === 0){
alert("该用户已存在")
} else {
this.$router.push('/index/xiaoxi');
}
}
},
methods:{
register(){
this.$router.push('/register')
},
login(){
this.$socket.emit('login',{username:this.username});
}
sockets: {
connect(){
},
//初始化所有在线的朋友
allFriend(data){
// 获取 除自己外所有 成员
this.friendList = data.users.filter((user,index)=>{
return this.username !== user.username;
});
}
},
created() {
//获取自己的名字
if (this.$store.state.user) {
this.username = this.$store.state.user;
} else {
this.$router.push('/login');
}
//初始化 好友列表
this.$socket.emit('allFriend');
},
methods: {
gotoChatRoom(username) {
//跳转时 带上 要发私信的用户名
this.$router.push('/chatRoom?tousername='+username);
}
}
export default {
data() {
return {
text: '',
username: "",
toUsername:'',
fromRouterPath: '',
btnDisabled: true,
socketID:'',
allChatInfo:{}
}
},
sockets: {
/**
* 此处的相关操作和 QQ.html 里面差不多
*/
connect(){ //监听连接是否成功
//连接成功 获取当前连接的ID
// this.socketID =this.$socket.id;
},
message(data){ //接收 服务器传来的数据
this.allChatInfo = data;
},
messageHistory(data){ //历史记录
this.allChatInfo = data;
}
},
beforeRouteEnter(to, from, next) {
next(vm => {
//获取上一次的路由//返回上一页
vm.fromRouterPath = from.fullPath;
})
},
created() {
//获取当前的用户名
this.username = this.$store.state.user;
//1,获取用户名(要发私信给他的那个)
this.toUsername = this.$route.query.tousername;
//初始化历史聊天记录
this.$socket.emit('messageHistory',{username:this.username});
// console.log(this.$socket); //当前socket对象
},
methods: {
sendClick() {
//3,发送给服务器(数据:发送的数据,to用户名,自己的用户名)
this.$socket.emit('send',{msg:this.text,toUser:this.toUsername,myUsername:this.username});
//发送给服务器 并且带上自己的socketID
// 注意 :这是默认的连接 也就是 '/' ------下面使用namespace
// this.$socket.emit('send',{data:this.text,socketID:this.socketID});
/*
namespace 发送一样
*/
// this.$socket.emit('namespaceSend',{data:this.text,socketID:this.socketID});
/*
房间
*/
// this.$socket.emit('send',{data:this.text,socketID:this.socketID});
//动态接收服务器给的值???
// this.sockets.subscribe('message', (data) => {
// console.log(data);
//销毁 动态添加的事件
// this.sockets.unsubscribe('message');
// });
//清空
this.text = '';
this.btnDisabled = true;
},
gotoBack() {
//返回上一页面
this.$router.push(this.fromRouterPath);
},
//判断是否有输入
isInput() {
if (this.text.trim().length > 0) {
this.btnDisabled = false;
} else {
this.btnDisabled = true;
}
}
},
filters:{
}
}
"use strict";
const app = require('express')(); //创建express实例 express作为中间件
const server = require('http').createServer(app); //创建http服务器
const io = require("socket.io")(server); //将创建的http服务添加到socket.io
const BodyParser = require('body-parser');
const cors = require('cors');
//配置post请求
// app.use(BodyParser.urlencoded({extended:false}));
// app.use(BodyParser.json());
//跨域
// app.use(cors({
// origin:["http://127.0.0.1:8080","http://192.168.43.122:8080",'http://localhost:8080'],
// methods:["POST","GET"],
// alloweHeaders:['Conten-type','Authorization']
// }));
let personNum = 0;
let users = []; //存储 用户信息(用户名,发送的信息,图片URL,avatarUrl)
let _sockets = {}; //以用户名 为键 存储socket连接(对应的映射)
io.on('connection',(socket)=>{
/**
* 实现私密聊天********************************************************
*/
socket.on('login',data=>{ //登录
socket.username = data.username;
if (data.username){
for (let user of users){
if (user.username === data.username){
socket.emit("login",{msg:'已经存在',code:0});
socket.username = null;
//如果已经存在 置为空 //下面判断 说明是旧用户,需要换一个用户名
break;
}
}
}
//不存在 保存起来 (新用户登录成功)
if (socket.username){
users.push({
username: data.username, //用户名
message: [], //消息
imgUrl: [], //发送的文件
styleSign:'', //个性签名
avatarUrl: 'https://img02.sogoucdn.com/net/a/04/link?appid=100520040&url=https://i04piccdn.sogoucdn.com/6a8cddcfaa27dddc'
});
// 告知其 自己 登录成功(前端使用vuex保存数据)
socket.emit('login',{msg:'登录成功', code:1, username:socket.username});
//登录成功广播 告知所有用户 上线了
io.emit('allFriend',{code:1,users})
}
//保存 socket (注意由于每次都是新的,所以需要更新或者保存)
_sockets[data.username] = socket;
//客户端朋友列表的初始化
socket.on('allFriend',()=>{
socket.emit('allFriend',{code:1,users});
});
//客户端历史消息初始化
socket.on('messageHistory',data=>{
for(let user of users){
if (data.username === user.username){
_sockets[data.username].emit('messageHistory',user);
break;
}
}
});
//接收发送的数据并为其做出反应
socket.on('send',data=>{
if (data.msg){
//先把数据存储起来
users.forEach((user,index)=>{
//在发送方保存一份(username是自己的名字),
// 在接收方保存一份(username都是对方的名字)
if (user.username === data.myUsername || user.username === data.toUser){
user.message.push({
username:data.myUsername, //用户名 是谁发的
userAndToUser:`${data.myUsername}${data.toUser}`, //和谁一起聊天的数据
message: data.msg //数据
})
}
//给自己一份数据
for (let user of users){
if (user.username === data.myUsername){
_sockets[data.myUsername].emit('message',user);
break;
}
}
});
//发送给指定的用户(返回他自己的数据即:to谁就把给他自己),如上还有发给自己一份
for(let user of users){
if (user.username === data.toUser){ //找到要发给他数据的那个人
_sockets[data.toUser].emit('message',user); //把她自己的数据发给她自己
break;
}
}
}
})
// console.log(users);
// console.log(_sockets);
});
/***********************************************************************
每位用户 连接后 都会有一个 属于他的 socket
也就是 socket 是一个对象 和
前端 this.$socket; 是同一个对象
参考文档:
https://www.cnblogs.com/edwardloveyou/p/10625152.html
https://socket.io/docs/ //官方文档
*/
let allUserSocket = [];
// console.log(socket);
/**
* 特别注意:这里绑定的msg 一定要与
* 前端 socket.on 接收数据绑定的 事件一样
*/
// socket.emit('message', { "name":'zt' });// 向客户端发送消息
// io.emit('msg',"所有客户端都能接收");//向所有客户端发送消息
// socket.on('send',function (data) { //接收客户端传来的
// broadcast 默认是向所有的socket连接进行广播,
// 但是不包括发送者自身,如果自己也打算接收消息的话,使用:io.emit。
// socket.broadcast.emit('message',data)
//
/***************************************************************************
* rooms 房间 暂时不会
*/
// socket.join('room');
// socket.on('send',function (data) {
// socket.broadcast.emit('message',data)
// 向房间里的所有客户端发送消息
// io.to('room').emit("message",data);
// });
// 默认房间(每一个id一个room)
// socket.on('send', (id, msg) => {
// console.log(id, msg);
// socket.broadcast.to(id).emit('message', msg);
// });
// socket.on('reply', () => {});
/*
断开连接
*/
socket.on('disconnect',()=>{
//删除退出聊天的人
//触发用户离开的监听
// socket.broadcast.emit("oneLeave",{username: socket.username});
users.forEach((user,index)=> {
if (user.username === socket.username) {
users.splice(index, 1);
}
});
console.log(socket.username + "先闪了");
// console.log(socket);
});
});
/************************************************************************************
* namespace 命名空间 某个功能模块 单独的连接
前端连接时 这样 [ 服务器IP/自己命名空间 ]
*/
const mypath = io.of('/mynamespace').on('connection',socket=>{
socket.on('namespaceSend',data=>{
console.log(data);
})
});
/***********************************************************************************
* 中间件 暂时忽略
*/
// const auth = (socket,next)=>{
// const data = socket.request;
// // if(!verify(data)){
// // throw new Error('not verify');
// // }
// next();
// };
// mypath.use(auth);
server.listen(3001,function () {
console.log("runing");
});