zoukankan      html  css  js  c++  java
  • uniapp中使用websocket实现实时聊天功能

    直接贴代码

    文档: https://uniapp.dcloud.io/api/request/websocket

    //scroll-view组件的scroll-top属性:设置竖向滚动条位置。只要scroll-top大于滚动区域最大高度,即可滚动到底部
    <scroll-view scroll-y="true" :scroll-top="commentScrollCount" class="comment-scroll-body">
          。。。。。。
    </scroll-view>
    
    
    
    data(){
          return{
              commentList:[],  //获取的评论列表
              commentValue:'',  //用户评论内容
              isSocketOpen:false,  //socket是否打开
              pingpangTimes:null,  //socket心跳计时器
          }
    }
    
    onLoad(option) {	
    	this.chatInit()  //socket相关操作				
    },
    
    beforeDestroy() {
    	clearInterval(this.pingpangTimes)  //清除socket心跳定时器
    	uni.closeSocket()  //关闭socket
    },
    methods:{
    //链接socket以进行直播实时评论发送获取等相关操作
    	chatInit(){
    		uni.request({
    			url: `${this.$baseUrl}/api-live/checkLiveStatus?lid=${this.lid}&initial=1`,  //此接口返回socket请求地址
    			method: 'GET',
    			success: res => {
    				if(res.data.code==200){
    					let socketlink=null
    					if(this.userToken){  //已登录,携带token
    						socketlink=`${res.data.msg}?token=${this.userToken}`
    					}else{  //未登录
    						socketlink=res.data.msg
    					}
    					this.commentList=[]  //创建新的socket连接前先清除之前的实时聊天记录
    					uni.closeSocket()  //创建新的socket连接前确保旧的已关闭
    					//创建一个socket连接
    					uni.connectSocket({
    						url:socketlink,
    						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形式再去解析内容
                                                    //后端规定cadmin为0--用户发言,为1--管理员发言,为2--系统提示,为3--需登录,为5--心跳信息
    						if(typeof(infos.cadmin)=="undefined"){  //infos.cadmin不存在说明返回的是数组,说明是第一次获取的之前的所有聊天记录
    							this.commentList=this.commentList.concat(infos)
                   //设置定时器,到时间后滚动到最底部。使用scroll-view组件的scroll-top属性。只要scroll-top的值大于滚动区域的最大高度即可实现滚动到最底部
    							let scrolltimes=setTimeout(()=>{  
    								this.commentScrollCount=this.commentList.length*200
    								clearTimeout(scrolltimes)
    							},600)
    
                                                         //后续每次更新一条有效的新聊天(心跳信息pong不是有效聊天),就会触发这个
    						}else if(infos.cadmin==0||infos.cadmin==1||infos.cadmin==2){
    							this.commentList=this.commentList.concat(infos)
    							let scrolltimes=setTimeout(()=>{
    								this.commentScrollCount=this.commentList.length*200
    								clearTimeout(scrolltimes)
    							},150)
    						}else if(infos.cadmin==3){  //未登录
    							this.loginPopRemind="您尚未登录或您的登录已过期,请重新登录后发言"
    							uni.removeStorageSync('kusername')
    							uni.removeStorageSync('kuserid')
    							uni.removeStorageSync('kuserimg')
    							uni.removeStorageSync('kusertoken')
    							this.$refs.noLoginPopup.open()
    						}
    					})
    					//先确保清除了之前的心跳定时器
    					clearInterval(this.pingpangTimes)
    					//每过一段时间发送一次心跳,发送Ping,服务器会反馈pong,这样操作以保持socket一直是连接状态,防止断开连接,心跳停止
    					this.pingpangTimes=setInterval(()=>{
    						uni.sendSocketMessage({
    							data: "ping",
    							success:()=>{},
    							fail:()=>{
    								this.isSocketOpen=false
    							}
    						});
    					},60000)
    				}
    			},
    		});
    	},
    			
    	//发表评论
    	sendComment(val){
    		if(val==""){
    			uni.showToast({title: '说点什么吧 ~',icon:'none'})
    		}else if(val.length>300){
    			uni.showToast({title: `评论字数请勿超过300个字符,当前 ${val.length}`,icon:'none'})
    		}else{
    			if(this.userToken){  //已登录
    				if(this.isSocketOpen){  //socket连接正常
    					this.commentValue=val
    					let theValue={
    						"ccontent":this.commentValue
    					}
    					let transedValue=JSON.stringify(theValue)   //后端规定的评论数据格式:json转字符串
    						uni.sendSocketMessage({
    							data: transedValue,
    							success:()=>{
    								this.commentValue=""
    								uni.showToast({title: '发送成功',icon:'none'})
    							},
    							fail:()=>{
    								uni.showToast({title: '发送失败,请稍后再试或重新进入此页面尝试',icon:'none'})
    							}
    						});
    				}else{  //socket已断开
    					uni.showToast({title: '聊天断开啦,请重新进入此页面尝试 ~',icon:'none'})
    				}
    			}else{  //未登录
    				this.$refs.needLoginPopup.open()
    			}
    		}
    	},
    }
    
  • 相关阅读:
    devexpress13学习系列(三)PDFViewer(3)
    devexpress13学习系列(一)PDFViewer(2)
    devexpress13学习系列(一)PDFViewer(1)
    Android图像处理之Bitmap类(zz)
    laravel 制作购物车流程
    数据类型转换
    http返回值
    前段框架
    开启GD拓展
    PHP初级程序员出路
  • 原文地址:https://www.cnblogs.com/huihuihero/p/13491922.html
Copyright © 2011-2022 走看看