uniapp APP websocket使用

uniapp APP websocket使用

本文章只是小弟在開發過程中所做的需求,踩坑過順便寫個博客用來做下筆記,如果代碼有什麼不足之處,希望大佬們指出,謝謝!
感覺能解決了問題的,動動小指頭點個贊~ O(∩_∩)O

** 1.此處說下我的需求:是通過websocket接受後端傳遞的數據,賦值到input輸入框,然後再進行一系列的操作,如果websocket鏈接失敗則彈窗提示,並且無限建立心跳鏈接,不允許斷開。廢話不多直接代碼截圖,本demo引入uview庫,需要demo在文章末尾會寫鏈接。**

websocket主要步驟:使用uniapp官網提供的API建立websocket鏈接,進入連接監聽,在失敗的監聽中設置定時器定時去發送連接,直到服務器連接成功,寫的過程中踩的坑莫名其妙,忘了如何描述,如果哪裏寫得不好請指點,第一次寫。

1、以下是html 調用的示例,代碼刪除了許多無關代碼,只需要看調用方法就行了。

<template>
	<view class="container">
		<!--  需求:通過websocket實時獲取數據,賦值到輸入框 ,如果websocket鏈接失敗則彈窗警告-->
		  <view class="content-left">
			     <!-- 掃描條碼 -->
				 <view class="textFontSize scan-container">
						<view class="mr-2 color-red font-w-b" style="font-size: 35rpx;">掃描條碼:</view>
						<view class="scanBox flex-1 mr-1">
								<input class="flex-1 pl-2" type="text" confirm-type="search" placeholder="請掃描載具條碼" v-model="scanCode"/>
						</view>
						<view class="scan-btn">
							<text class="iconfont icon-dagou"></text>
							<text class="ml-2">掃描提交</text>
						</view>
				 </view>
				 
		  </view>  
		   <!-- websocket連接失敗彈窗 -->
		   <u-mask :show="socketShow" >
		   		<view class="warp">
		   			<u-tag :text="webtext" mode="dark" class="warp-tag" type="error"/>
		   		</view>
		   	</u-mask>
	</view>
</template>
<script>

import {
   
    websocetObj } from '@/utils/websocet/websocet.js';

export default {
   
   
data() {
   
   
	return {
   
   
		     socketShow:false,
			webtext:'',
			
	  }
},
		methods: {
   
   
			//websocet函數回調:返回監聽的數據
			getWebsocetData(val){
   
   
				console.log(val,'函數回調');
				this.scanCode = val;
			},
			//websocet函數拋錯: 返回錯誤信息 用於用戶提示
			getWebsocetError(err){
   
   
				this.socketShow = err.isShow;
			    this.webtext = err.messge;
				console.log('websocet函數拋錯',this.socketShow);
			},
			//websocet函數成功進入: 監聽連接狀態,在失敗的時候彈窗提示,具體需求看自身情況
			onErrorSucceed(val){
   
   
				this.socketShow = val.isShow;
				console.log('websocet函數成功進入',this.socketShow);
			}   
		},
		mounted() {
   
   
		},
		onLoad() {
   
   
	    // 在onload的時候調用,創建webscoet連接對象,參數分別爲:url、獲取後端返回數據、監聽websocket的鏈接失敗返回的報錯、監聽鏈接狀態,返回布爾值
			websocetObj.sokcet('ws://192.168.xxxx',this.getWebsocetData,this.getWebsocetError,this.onErrorSucceed)
		
    },
    //離開頁面銷燬websocket
		beforeDestroy() {
   
   
			websocetObj.stop();
	   },
	}
</script>

2、以下是JS封裝的代碼

let isSocketClose=false;    // 是否關閉socket
let reconnectCount=5;    // 重連次數
let heartbeatInterval="";   // 心跳定時器
let socketTask = null;//websocket對象

let  againTimer = null;//斷線重連定時器

//此處變量用於斷線重連的調用傳參
let url = null; 
let onReFn = null;
let onSucFn = null;
let onErrFn = null;

/**
 * sockeUrl:websocet的地址
 * onReceive:消息監聽的回調
 * onErrorEvent:拋出錯誤的回調,且彈窗連接失敗的提示框
 * onErrorSucceed:拋出成功回調,主要用於隱藏連接失敗的提示框
 * */
const sokcet= (sockeUrl = 'ws://192.168.xxx' ,onReceive,onErrorEvent,onErrorSucceed)=> {
   
   
	           url = sockeUrl;
			   onReFn= onReceive;
			   onErrFn= onErrorEvent;
			   onSucFn= onErrorSucceed;
			   isSocketClose=false; 
	          //判斷是否有websocet對象,有的話清空
	           if(socketTask){
   
   
				   socketTask.close();
				   socketTask = null;
				   clearInterval(heartbeatInterval);
			   }
	
			   //WebSocket的地址
				// 【非常重要】必須確保你的服務器是成功的,如果是手機測試千萬別使用ws://127.0.0.1:9099【特別容易犯的錯誤】
				let url = sockeUrl
				// 連接
			socketTask = uni.connectSocket({
   
   
					url: url,
					success(data) {
   
   
								console.log("websocket連接成功");
								clearInterval(againTimer)//斷線重連定時器
							},
					fail: (err) => {
   
   
						console.log("報錯",err);
					}
				});
				
				// 連接打開
				socketTask.onOpen((res)=>{
   
   
					console.log('WebSocket打開');
					clearInterval(againTimer)//斷線重連定時器
					 onErrorSucceed({
   
   isShow:false}) // 用於提示框的隱藏
					heartbeatInterval && clearInterval(heartbeatInterval);
					// 10秒發送一次心跳
					heartbeatInterval = setInterval(() => {
   
   
						sendMsg('心跳ing')
					}, 1000*10)
				})
				 // 監聽連接失敗
				socketTask.onError((err)=>{
   
   
					console.log('WebSocket連接打開失敗,請檢查',err);
					//停止發送心跳
					clearInterval(heartbeatInterval)
					//如果不是人爲關閉的話,進行重連
					if (!isSocketClose) {
   
    
						reconnect(url,onErrorEvent)
					}
				})
			 
				// // 監聽連接關閉 -
				socketTask.onClose((e) => {
   
   
							console.log('WebSocket連接關閉!');
							clearInterval(heartbeatInterval)
							if (!isSocketClose) {
   
   
								reconnect(url,onErrorEvent)
							}
					})

				// 監聽收到信息
				socketTask.onMessage((res) => {
   
   
						uni.hideLoading()
						console.log(res,'res監聽收到信息')
						let serverData = res.data
						//與後端規定好返回值分別代表什麼,寫業務邏輯
						  serverData && onReceive(serverData);
				});
				
			
}

	const reconnect = (url,onErrorEvent)=>{
   
   
				 console.log('進入斷線重連',isSocketClose);
				     clearInterval(againTimer)//斷線重連定時器
				     clearInterval(heartbeatInterval);
					 socketTask.close(); // 確保已經關閉後再重新打開
					 socketTask = null;
					onErrorEvent({
   
   isShow:true,messge:'掃描頭服務正在連接...'})
					// 連接  重新調用創建websocet方法
			againTimer	= setInterval(()=>{
   
   
					 sokcet(url,onReFn,onErrFn,onSucFn)
					 console.log('在重新連接中...');
				 },1000*5)
					
										
		}	

  const sendMsg = (msg)=>{
   
      //向後端發送命令
                msg = JSON.stringify(msg)
                try{
   
   
                    //通過 WebSocket 連接發送數據
                    socketTask.send({
   
   
                        data: msg
                    });
                }catch(e){
   
   
                    socketTask.close({
   
   
						success(res) {
   
   
							console.log("關閉成功", res)
						},
						fail(err) {
   
   
							console.log("關閉失敗", err)
						}
					})

                }
            }
// 關閉websocket【必須在實例銷燬之前關閉,否則會是underfined錯誤】beforeDestroy() {websocetObj.stop();}
			
const stop = ()=>{
   
   
	clearInterval(heartbeatInterval);
	clearInterval(againTimer)//斷線重連定時器
	socketTask.close(); // 確保已經關閉後再重新打開
	socketTask = null;

}
 export const websocetObj = {
   
   
 	sokcet,
 	stop,
	sendMsg
 };
 

本文章的demo案例鏈接(裏面包含了uniapp在線預覽pdf的操作,只查看websocket就行了):https://gitee.com/ZhouLoveBrother/uniapp-websocket-pdf。
關於uniapp app 在線預覽pdf文章:https://blog.csdn.net/ZhouLoverBrother/article/details/111148025

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章