uniapp 使用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){
			// val = String.fromCharCode.apply(null, new Uint8Array(val)).trim()  如果后端返回数据格式是其他的,可能需要转换一下,比如这个,应该是转Unicode编码
				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,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*5)
				})
				 // 监听连接失败
				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 && 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){
					if(isSocketClose){
						return
					}else{
						reconnect(url,onErrFn)
					}

                }
            }
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}
			
const stop = ()=>{
	     isSocketClose = true
        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

  • 20
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值