在最近通过uniapp开发的项目中,用到了webSocket技术来实现聊天功能,由于是第一次写这样的代码,碰到了不少坑和弯路,但是结果还是可以的,开发出来的聊天效果非常顺滑,远远超过普通的接口实时查询,总之很赞。同样的,我作为一个新手开始摸坑uniapp的webSocket也是比较麻烦的,网上的教程很多不可用或者残缺,官方的文档总是那么的简洁让刚入门的不是很好理解,所以还是整理一个文档自己记录,以及方便阅读的人。
实际上,通过这一轮折腾,感觉聊天软件和视频直播,视频对话,在第三方SDK的帮助下,也就是简简单单弄完的事情。
废话结束,开始代码安排
一:首先定义好数据字段,和本地存储方法
1.先定义好要用到的字段,包括消息列表,房间号,用户ID,用户名等等一系列
data() {
return {
message:'', //消息内容
userName:"", //我的账号
userID:0, //我的用户ID
messageList:[], //消息列表
myName:"", //我的用户昵称
friendID:0, //好友的用户昵称
friendAccount:'', //好友的账号
roomID:"", //房间ID
};
},
2.先在项目内安装mp-storage插件,它是个非常好用支持多平台的本地数据存储解决方案,安装完成后,引入方法如下。
import { localStorage } from '../../js_sdk/mp-storage/mp-storage/index.js'
3.在项目内定义两个本地数据存储方法,一个用来存入数据,一个用来取出数据(localStorage只能存字符串,所以存就是把json转字符串再存,取就是取出来再转为JSON)
//聊天数据存储到本地
localData(data){
const that = this;
var friendID = that.friendID;
var dataname = "chat"+friendID;
var data = JSON.stringify(data);
localStorage.setItem(dataname, data);
that.getlocalData();
},
getlocalData(){
const that = this;
var friendID = that.friendID;
var dataname = "chat"+friendID;
var data = localStorage.getItem(dataname);
data = JSON.parse(data);
that.messageList = data;
setTimeout(() => {
uni.pageScrollTo({
scrollTop: 999999,
duration: 0
});
}, 200);
},
二:主要功能的实现
1.在这个项目中采用的逻辑是创建websocket房间,加入房间的人就就可以相互对话,然后实现一对一的聊天,和多人的群聊。所以在参考了官方的文档后,写了以下的代码,用来实现websocket的状态监听和心跳监听。
// 进入这个页面的时候创建websocket连接[整个页面随时使用]
connectSocketInit(){
var that = this;
var serverHot = websocket接口网址;
var sid = that.roomID; //房间号
var nickname = that.myName; //用户昵称
var url = 'ws://' + serverHot + '/groupChat/' + sid + '/' + nickname;
uni.closeSocket() //创建新的socket连接前确保旧的已关闭
//创建一个socket连接
uni.connectSocket({
url:url,
success: res=>{}
})
//监听socket打开
uni.onSocketOpen(()=>{
this.isSocketOpen=true
console.log('WebSocket连接已打开!');
})
//监听socket关闭
uni.onSocketClose(()=>{
this.isSocketOpen=false
console.log('WebSocket连接已关闭!');
})
//监听socket错误
uni.onSocketError(()=>{
this.isSocketOpen=false
console.log('WebSocket连接打开失败');
})
//监听socket消息
uni.onSocketMessage((res)=>{
//let infos=JSON.parse(res.data) //socket信息是字符串,需要先转成json形式再去解析内容
console.log(res);
if(res.data=="ping"){ //判断消息类型是否为用来监听链接的ping,如果是则不继续执行只是控制台显示
console.log("通信检测成功")
return false;
}
var data = "["+res.data+"]"; //返回的字符串拼接中括号,后面转为JSON数组
data=JSON.parse(data); //转为JSON数组
var messageList = that.messageList; //获取现有消息队列
if(messageList.length>0){
messageList = messageList.concat(data); //如果长度大于0就拼接websocket返回消息
}else{
messageList = data; //否则直接等于
}
that.messageList = messageList; //赋值消息列表
that.localData(that.messageList); //存入本地数据,并渲染
})
//先确保清除了之前的心跳定时器
clearInterval(this.pingpangTimes)
//每过一段时间发送一次心跳,发送Ping,服务器会反馈pong,这样操作以保持socket一直是连接状态,防止断开连接,心跳停止
this.pingpangTimes=setInterval(()=>{
uni.sendSocketMessage({
data: "ping",
success:()=>{},
fail:()=>{
this.isSocketOpen=false
}
});
},30000)
},
2.定义发送消息的方法,所以肯定还要先绑定一个输入框
<input v-model="message"></input>
然后定义发送方法(websocket只能发送字符串消息,那么我可以自定义json,先转成字符串再发送出去,所以接收那边也是先接收到发送的字符串并强行再转化为JSON
):
send() {
const that = this;
var type = 2;
if(that.message==""){
uni.showToast({
icon: 'none',
title: '请输入消息内容',
position:'bottom'
});
return false;
}
var data={
userName:that.userName,
userId:that.userID,
message:that.message,
time:that.getDate(),
imtype:type,
friendID:that.friendID
}
console.log(JSON.stringify(data));
data=JSON.stringify(data);
uni.sendSocketMessage({
data: data,
success:()=>{
//发送成功的方法
},
fail:()=>{
}
});
that.message = "";
},
3.就这样,数据的发送,读取,存入本地,和websocket连接就完成了,通过messageList字段就可以直接循环存在本地的数据列表,开始在页面上渲染了。
<view v-for="(item,index) in messageList">
//循环渲染内容区域
</view>
项目实例就不好分享了,到时候我直接给博客加个站内websocket玩一玩试试,应该也很有意思。
本文来自投稿,不代表本站立场,如若转载,请注明出处:https://www.ruletree.club/archives/2108/