uniapp连接webSocket实例,收发数据存储到本地,详细教程

在最近通过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玩一玩试试,应该也很有意思。

timg.jpg

您的大名:
万水千山总是情,给个打赏行不行。 打赏
原创文章,作者:不暇,如若转载,请注明出处:https://www.ruletree.club/archives/2108/
报读保安课程3个理由,打造和谐保安团队
« 上一篇 08-26
uniapp对接oss,实现图片上传
下一篇 » 09-16

发表评论

已有 2 条评论

  1. 葱子Lv.1 说道:

    目前在uniapp中使用websocket来讲,我感觉还是GoEasy提供的websocket服务更好,稳定性不错,消息实时性也好,采用发布/订阅模式,使用起来也蛮方便的

    1. 不暇VLv.6 说道:

      主要在于当时做开发的时候websocket服务是自建的,不是用第三方,所以就用了目前这个可以自由diy的插件了

作者信息

热门文章

标签TAG

热评文章