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