赞
踩
在业务中需要使用webSocket定时给后台上传位置,防止以后忘记,在这里进行记录,直接在代码中写入笔记;
- <template>
- <div id='main' ref='main'>
- <van-button @click="OnLocation">开启</van-button>
- <van-button @click="OnClose">关闭socket</van-button>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- lc: {}, // 经纬度
- ws: null, // webSocket实例
- webSocketState: false, // webSocket的连接状态
- heartBeat: { // 心跳连接的时间设置
- time: 5 * 1000, // 心跳时间间隔
- timeout: 3 * 1000, // timeout:心跳超时间隔(!要少于心跳间隔)
- reconnect: 10 * 1000 // 断线重连时间
- },
- reconnectTimer: null, // 断线重连时间器
- }
- },
- methods: {
- OnClose() {
- this.ws.close(); //关闭webSocket连接
- this.webSocketState = false; //关闭状态
- this.heartBeat.time = null; //停止心跳
- if (this.reconnectTimer) { //关闭重连
- clearInterval(this.reconnectTimer);
- }
- },
- //开启按钮
- OnLocation() {
- this.heartBeat.time = 5 * 1000; //因为关闭时会置空,所以在这重新初始化一下
- this.wlhy.getLocation(); //这里是我自己业务中取经纬度的,
- this.connectWebSocket(); //建立连接
- },
- //socket链接
- connectWebSocket() {
- let url = `wss://ws://baidu.com/msg/${this.userInfo.userId}`;
- //这里连接地址根据自己的业务设置,注意:如果连接本地进行调试的时候,要用'ws',如:“ws://192.168.2.15:8080/msg”
- this.ws = new WebSocket(url);
- this.init(); //初始化
- },
- init() {
- this.ws.addEventListener('open', () => {
- // eslint-disable-next-line spaced-comment
- this.webSocketState = true; //socket状态设置为连接,做为后面的断线重连的拦截器
- // eslint-disable-next-line no-unused-expressions
- console.log('开启');
- this.heartBeat && this.heartBeat.time ? this.startHeartBeat(this.heartBeat.time) : ''; // 是否启动心跳机制
- });
- this.ws.addEventListener('message', (e) => {
- this.webSocketState = true;
- console.log(JSON.parse(e.data),'信息')
- });
- this.ws.addEventListener('close', (e) => {
- this.webSocketState = false; // socket状态设置为断线
- console.log('断开了连接');
- });
- this.ws.addEventListener('error', (e) => {
- this.webSocketState = false; // socket状态设置为断线
- this.reconnectWebSocket(); // 重连
- console.log('连接发生了错误');
- });
- },
- // 心跳 time:心跳时间间隔
- startHeartBeat(time) {
- setTimeout(() => {
- //这里设置这是你要发送的内容
- let data = {};
- data.lon = this.lc.longitude; //已省略获取地址步骤
- data.lat = this.lc.latitude;
- this.ws.send(JSON.stringify(data)) //发送数据
- this.waitingServer();
- }, time);
- },
- // 延时等待服务端响应,通过webSocketState判断是否连线成功
- waitingServer() {
- this.webSocketState = false;
- setTimeout(() => {
- if (this.webSocketState) {
- this.startHeartBeat(this.heartBeat.time);
- return;
- }
- console.log('心跳无响应,已断线');
- try {
- this.ws.close();
- } catch (e) {
- console.log('连接已关闭,无需关闭');
- }
- this.reconnectWebSocket(); //非主动关闭导致,触发重连
- }, this.heartBeat.timeout);
- },
- // 重连操作
- reconnectWebSocket() {
- this.reconnectTimer = setTimeout(() => {
- this.reconnectWs();
- }, this.heartBeat.reconnect);
- },
- reconnectWs() {
- if(!this.heartBeat.time) return //如果主动关闭,则防止重连
- if (!this.ws) {
- // 第一次执行,初始化
- this.connectWebSocket();
- }
- if (this.ws && this.reconnectTimer) {
- // 防止多个websocket同时执行
- clearTimeout(this.reconnectTimer);
- this.ws.reconnectTimer = null;
- this.connectWebSocket();
- }
- },
- },
-
- }
- </script>

注意:我在开发过程中发现,当我主动关闭连接后,在重连时间内会自动重新开启连接,这是因为websocket连接关闭会又走一次重连机制,所以 如果你是使用的定时器,可以直接清除定时器,或者定义一个变量控制是组件销毁关闭的websocket还是心跳监测重连时关闭的websocket,如果是像我一样,可以判断this.heartBeat.time,关闭后置空,判断return就可以了;
下面是直接用定时器做的心跳(在这里没有主动关闭的功能)
- <script>
- export default {
- name: "clockIn",
- data(){
- return {
- lc: {}, //经纬度(获取过程省略)
- interval: null, //定时器
- socket: null, //socket
- }
- },
- mounted() {},
- methods: {
- initSocket() {
- /**主流浏览器都支持 webSocket 通信,但建议还是要判断*/
- if ("WebSocket" in window) {
- if (this.socket) {
- this.socket.close();
- }
- /**创建 web socket 实例
- * 如果连接失败,浏览器控制台报错,连接失败
- * 前缀 ws:// 必须正确,weChatInteract 是应用名称,webSocket/shake.action 是后台访问路径
- * */
-
- let url = `ws://192.168.2.15:8080/msg`;
- this.socket = new WebSocket(url);
-
- let _this = this;
- /**onopen:服务器连接成功后,自动触发*/
- this.socket.onopen = function() {
- this.interval = setInterval(function() {
- /** Web Socket 已连接上,使用 send() 方法发送数据*/
- let data = {};
- data.lon = lc.longitude;
- data.lat = lc.latitude;
- console.log(data)
- _this.socket.send(JSON.stringify(data))
- console.log("服务器连接成功,并发送数据到后台...");
- },30000)
- }
-
- /**服务器发送数据后,自动触发此方法,客户端进行获取数据,使用 evt.data 获取数据*/
- this.socket.onmessage = function(msg) {
- if (msg.data && msg.data != 'messageCenter login success') {
- // let message = JSON.parse(msg.data);
- console.log(message,'=> 接收到服务器数据')
- }
- }
-
- /**客户端与服务器数据传输错误时触发*/
- this.socket.onerror = function (evt) {
- console.log("客户端 与 服务器 数据传输错误...");
- };
-
- /**web Socket 连接关闭时触发*/
- this.socket.onclose = function(e) {
- console.log("web scoket 连接关闭...");
- if (this.interval) {
- clearInterval(this.interval);
- }
- setTimeout(function() {
- _this.initSocket();
- },5000)
- }
-
- } else {
- console.log("浏览器不支持 WebSocket!");
- }
- },
- },
- </script>

参考链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。