本基于Java Websocket Vue.js实现仿微信即时通讯聊天APP系统,采用面向对象思想,选用Vue.js技术实现APP端聊天界面,后台选用JavaSSM轻量级开发框架,采用websocket实现客户端与服务端的及时通信。系统主要界面功能仿照微信实现,具备聊天通讯录,我的朋友圈,个人信息等模块。
原文地址
一、程序设计
本次基于Java Websocket Vue.js实现仿微信即时通讯聊天APP系统主要内容涉及:
主要功能模块:注册登录、聊天列表、发现页面、通讯录、我的页面、聊天窗口、好友界面等等
主要包含技术:spring,SSM,Mysql,vue,html,css,websocket
主要包含算法:协同过滤好友推荐
二、效果实现
用户登录及朋友圈
聊天及通讯录
好友添加
其他效果省略
三、核心代码
本次基于Java Websocket Vue.js实现仿微信即时通讯聊天APP系统,在用户及时通讯主要采用websocket技术。在HTML5中,为了加强web的功能,提供了websocket技术,它不仅是一种web通信方式,也是一种应用层协议。它提供了浏览器和服务器之间原生的双全工跨域通信,通过浏览器和服务器之间建立websocket连接(实际上是TCP连接),在同一时刻能够实现客户端到服务器和服务器到客户端的数据发送。
首先是客户端new 一个websocket对象,该对象会发送一个http请求到服务端,服务端发现这是个webscoket请求,会同意协议转换,发送回客户端一个101状态码的response,以上过程称之为一次握手,经过这次握手之后,客户端就和服务端建立了一条TCP连接,在该连接上,服务端和客户端就可以进行双向通信了。这时的双向通信在应用层走的就是ws或者wss协议了,和http就没有关系了。所谓的ws协议,就是要求客户端和服务端遵循某种格式发送数据报文(帧),然后对方才能够理解。
核心实现源码
代码语言:txt复制 //握手成功之后就可以发送数据了
var crypto = require('crypto');
var WS = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
var server=require('net').createServer(function (socket) {
var key;
socket.on('data', function (msg) {
if (!key) {
//获取发送过来的Sec-WebSocket-key首部
key = msg.toString().match(/Sec-WebSocket-Key: (. )/)[1];
key = crypto.createHash('sha1').update(key WS).digest('base64');
socket.write('HTTP/1.1 101 Switching Protocolsrn');
socket.write('Upgrade: WebSocketrn');
socket.write('Connection: Upgradern');
//将确认后的key发送回去
socket.write('Sec-WebSocket-Accept: ' key 'rn');
//输出空行,结束Http头
socket.write('rn');
} else {
var msg=decodeData(msg);
console.log(msg);
//如果客户端发送的操作码为8,表示断开连接,关闭TCP连接并退出应用程序
if(msg.Opcode==8){
socket.end();
server.unref();
}else{
socket.write(encodeData({FIN:1,
Opcode:1,
PayloadData:"接受到的数据为" msg.PayloadData}));
}
}
});
});
server.listen(8000,'localhost');
//按照websocket数据帧格式提取数据
function decodeData(e){
var i=0,j,s,frame={
//解析前两个字节的基本数据
FIN:e[i]>>7,Opcode:e[i ]&15,Mask:e[i]>>7,
PayloadLength:e[i ]&0x7F
};
//处理特殊长度126和127
if(frame.PayloadLength==126)
frame.length=(e[i ]<<8) e[i ];
if(frame.PayloadLength==127)
i =4, //长度一般用四字节的整型,前四个字节通常为长整形留空的
frame.length=(e[i ]<<24) (e[i ]<<16) (e[i ]<<8) e[i ];
//判断是否使用掩码
if(frame.Mask){
//获取掩码实体
frame.MaskingKey=[e[i ],e[i ],e[i ],e[i ]];
//对数据和掩码做异或运算
for(j=0,s=[];j<frame.PayloadLength;j )
s.push(e[i j]^frame.MaskingKey[j%4]);
}else s=e.slice(i,frame.PayloadLength); //否则直接使用数据
//数组转换成缓冲区来使用
s=new Buffer(s);
//如果有必要则把缓冲区转换成字符串来使用
if(frame.Opcode==1)s=s.toString();
//设置上数据部分
frame.PayloadData=s;
//返回数据帧
return frame;
}
//对发送数据进行编码
function encodeData(e){
var s=[],o=new Buffer(e.PayloadData),l=o.length;
//输入第一个字节
s.push((e.FIN<<7) e.Opcode);
//输入第二个字节,判断它的长度并放入相应的后续长度消息
//永远不使用掩码
if(l<126)s.push(l);
else if(l<0x10000)s.push(126,(l&0xFF00)>>2,l&0xFF);
else s.push(
127, 0,0,0,0, //8字节数据,前4字节一般没用留空
(l&0xFF000000)>>6,(l&0xFF0000)>>4,(l&0xFF00)>>2,l&0xFF
);
//返回头部分和数据部分的合并缓冲区
return Buffer.concat([new Buffer(s),o]);
}