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()
			}
		}
	},
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM