前端实现websocket类封装

这篇具有很好参考价值的文章主要介绍了前端实现websocket类封装。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

随着Web应用程序的发展,越来越多的人开始利用Websocket技术来构建实时应用程序。Websocket是一种在客户端和服务器之间建立持久连接的协议。这种协议可以在一个单独的连接上实现双向通信。与HTTP请求-响应模型不同,Websocket允许服务器自主地向客户端发送数据。这种实时连接的能力使得Websocket在许多应用场景中得到了广泛的应用。

Websocket技术的优点之一是减少了网络延迟。在传统的HTTP请求-响应模型中,客户端必须不断地向服务器发送请求以获取更新的数据。这种不断的请求-响应循环会占用大量的带宽和处理能力。而Websocket的持久连接可以在服务器有新数据时立即向客户端发送,从而减少了网络延迟和服务器负载。

另一个优点是Websocket可以处理大量的并发连接。在传统的HTTP请求-响应模型中,每个请求都必须在服务器上进行处理,这可能会对服务器造成负载压力。但是,Websocket的持久连接可以在服务器上保持打开状态,从而减少了与每个连接相关的开销。这使得服务器可以处理大量的并发连接而不会降低性能。

Websocket还可以用于实时通信。例如,聊天应用程序可以使用Websocket来实现实时消息传递。在这种情况下,Websocket的持久连接可以在服务器上保持打开状态,以便客户端可以接收实时消息。这种实时通信的能力使得Websocket在许多应用程序中得到了广泛的应用。

总之,Websocket技术在现代Web应用程序中发挥着越来越重要的作用。它可以减少网络延迟和服务器负载,处理大量的并发连接,并提供实时通信能力。因此,如果您正在构建一个需要实时更新的Web应用程序,那么Websocket技术可能是您的理想选择。

封装类实现

import { WebSocketConfigOption } from './WebSocketConfigOption';

export class ReconnectableWebSocket {

   private ws!: WebSocket; // ws实例
   private opt: WebSocketConfigOption; // ws配置项
   private lockReconnect: boolean = false; // 避免ws重复连接
   private isClosingWindow: boolean = false;
   private reconnectTimeout: any;
   private heartSendInterval: any;

   constructor(option: WebSocketConfigOption) {
      if (null === option.url || '' === option.url) {
         throw ('url不能为空');
      }
      this.opt = option;
      this.initWebSocket();
   }

   private initWebSocket() {
      if (null == this.opt.secWebSocketProtocol) {
         this.ws = new WebSocket(this.opt.url);
      } else if (this.opt.secWebSocketProtocol.length == 0) {
         this.ws = new WebSocket(this.opt.url);
      } else {
         this.ws = new WebSocket(this.opt.url, this.opt.secWebSocketProtocol);
      }
      this.initEventHandle();
      window.onbeforeunload = () => {
         this.isClosingWindow = true;
         this.ws.close(); // 当窗口关闭时,主动去关闭websocket连接。
      }
   }

   private initEventHandle() {
      this.ws.onclose = () => {
         console.log('ws连接关闭!' + this.opt.url);
         this.opt.onclose && this.opt.onclose();
         this.heartCheckStop();
         if (!this.isClosingWindow) {
            this.reconnect();
         }
      }
      this.ws.onerror = () => {
         console.log('ws连接错误!' + this.opt.url);
         this.opt.onerror && this.opt.onerror();
         this.heartCheckStop();
         if (!this.isClosingWindow) {
            this.reconnect();
         }
      }
      this.ws.onopen = () => {
         console.log('ws连接成功!' + this.opt.url);
         this.opt.onopen && this.opt.onopen();
         this.heartCheckStart();
      }
      this.ws.onmessage = (event: any) => {
         this.opt.onmessage && this.opt.onmessage(event);
      }
   }

   /** 重连 */
   private reconnect() {
      if (this.lockReconnect) {
         return;
      }
      this.lockReconnect = true;
      this.reconnectTimeout = setTimeout(() => {
         this.initWebSocket();
         this.lockReconnect = false;
      }, 2000);
   }

   /** 关闭重连 */
   private reconnectStop(): void {
      clearTimeout(this.reconnectTimeout);
   }

   /** 开启心跳包保持连接 */
   private heartCheckStart(): void {
      this.ws.send('heartCheck');
      this.heartSendInterval = setInterval(() => {
         this.ws.send('heartCheck');
      }, 5 * 60 * 1000);
   }

   /** 关闭心跳包 */
   private heartCheckStop(): void {
      clearInterval(this.heartSendInterval);
   }

   /** 主动关闭连接 */
   public close(): void {
      this.reconnectStop();
      this.heartCheckStop();
      this.isClosingWindow = true;
      this.ws.close();
   }

}

配置类实现

export type WebSocketConfigOption = {

   url: string;
   secWebSocketProtocol?: Array<string>;
   onopen?: () => void;
   onmessage?: (msg: any) => void;
   onerror?: () => void;
   onclose?: () => void;

}

应用示例

import { WebSocketConfigOption } from '../websocket/WebSocketConfigOption';
import { ReconnectableWebSocket } from '../websocket/ReconnectableWebSocket';
import { InnerMqService } from '../../rx/inner-mq.service';

export class MapMessageConnection {

   private ws!: ReconnectableWebSocket;

   constructor(
      private path: string,
      private innerMqService: InnerMqService,
   ) {
      this.connection();
   }

   /** 连接 */
   private connection(): void {
      let wsConfig: WebSocketConfigOption = {
         url: this.path,
         onopen: () => {
         },
         onerror: () => {
         },
         onmessage: (msg: any) => {
            if (msg.data && msg.data !== '') {
               let data = JSON.parse(msg.data);
               this.innerMqService.pub(data.title, data.content);
            }
         }
      }
      this.ws = new ReconnectableWebSocket(wsConfig);
   }

   /** 断开连接 */
   public disConnection(): void {
      this.ws.close();
   }

}
import { InnerMqClient } from '../../rx/inner-mq.service';
import { SubmitService } from '../../service/submit.service';
import { MapBase } from '../../map/map-base';
import { CommonUtil } from '../../util/common-util';
import { MapPage } from '../../view/page/map/map.page';
import { MapDraw } from '../../map/draw/map-draw';
import { MapWrap } from '../../map/draw/map-wrap';
import { GeoUtil } from "../../map/geo-util";
import { Point } from "../../map/entity/Point";

export class MapMessageProcessor {

   constructor(
      private mqClient: InnerMqClient,
      private submitService: SubmitService,
      private mapBase: MapBase,
      private mapPage: MapPage,
   ) {
      /** 放大 */
      mqClient.sub('ZoomIn').subscribe((res) => {
         mapBase.zoomIn();
      });
      /** 缩小 */
      mqClient.sub('ZoomOut').subscribe((res) => {
         mapBase.zoomOut();
      });
      /** 拖动 */
      mqClient.sub('Pan').subscribe((res) => {
         mapBase.pan();
      });
      /** 显示网格 */
      mqClient.sub('GridSwitch').subscribe((res) => {
         let update;
         if (mapBase.getGridVisible()) {
            mapBase.closeGrid();
            update = false;
         } else {
            mapBase.showGrid();
            update = true;
         }
         let config = mapBase.getMapConfig();
         if (config) {
            config.grid = update;
            CommonUtil.setConfigCache(config);
            mapBase.setMapConfig(config);
         }
      });
      /** 切换图层源 */
      mqClient.sub('SwitchResource').subscribe((res) => {
         // 切换图层
         debugger
         let lastType = mapBase.getCurrentCoordinateType();
         mapBase.switchMapResource(res);
         let currentType = mapBase.getCurrentCoordinateType();
         // 保存设置
         let config = mapBase.getMapConfig();
         if (config) {
            config.layer = res;
            CommonUtil.setConfigCache(config);
            mapBase.setMapConfig(config);
         }
         // 检查坐标类型
         if (lastType != currentType) {
            if (lastType == 'wgs84' && currentType == 'gcj02') {
               mapBase.turnMapFeaturesFromWgs84ToGcj02();
            } else if (lastType == 'gcj02' && currentType == 'wgs84') {
               mapBase.turnMapFeaturesFromGcj02ToWgs84();
            }
         }
         // 回调
         setTimeout(() => {
            mapPage.updateShowInfo();
         });
      });
      /** 绘制类型切换 - */
      mqClient.sub('SwitchDrawType').subscribe((res) => {
         mapBase.setDrawType(res);
      });
      /** 绘制 - */
      mqClient.sub('OpenDraw').subscribe((res) => {
         mapBase.pan();
         mapBase.removeDrawedFeatures();
         mapBase.openDraw({
            drawEnd: () => {
               setTimeout(() => {
                  mapBase.removeDrawInteraction();
               })
            },
            modifyEnd: () => {
            }
         });
      });
      /** 绘制指定多边形并定位 - */
      mqClient.sub('DrawPolygonAndPositioning').subscribe((res) => {
         mapBase.pan();
         mapBase.removeDrawedFeatures();
         let blocks = JSON.parse(res);
         for (let i = 0; i < blocks.length; i++) {
            let points: Array<Point> = [];
            for (let j = 0; j < blocks[i].length; j++) {
               let point = new Point(blocks[i][j].lng, blocks[i][j].lat);
               if (mapBase.getCurrentCoordinateType() == 'wgs84') {
                  points.push(GeoUtil.gcj02_To_wgs84(point));
               } else {
                  points.push(point);
               }
            }
            let feature = MapDraw.createPolygonFeature(points);
            MapWrap.addFeature(mapBase, mapBase.drawLayerName, feature);
         }
         mapBase.setFitviewFromDrawLayer();
      });
      /** fitview - */
      mqClient.sub('Fitview').subscribe((res) => {
         mapBase.setFitviewFromDrawLayer();
      });
      /** 删除绘制 - */
      mqClient.sub('RemoveDrawedShape').subscribe((res) => {
         mapBase.removeDrawedFeatures();
      });
      /** 提交区块下载 - */
      mqClient.sub('SubmitBlockDownload').subscribe((res) => {
         let data = {
            tileName: this.mapBase?.getCurrentXyzName(),
            mapType: CommonUtil.getMapType(this.mapBase?.getCurrentXyzName()),
            tileUrl: this.mapBase?.getCurrentXyzUrlResources(),
            points: this.mapBase?.getDrawedPoints(),
         };
         this.submitService.blockDownload(data).then((r) => {
         });
      });
      /** 提交世界下载 - */
      mqClient.sub('SubmitWorldDownload').subscribe((res) => {
         let data = {
            tileName: this.mapBase?.getCurrentXyzName(),
            mapType: CommonUtil.getMapType(this.mapBase?.getCurrentXyzName()),
            tileUrl: this.mapBase?.getCurrentXyzUrlResources()
         };
         this.submitService.worldDownload(data).then((r) => {
         });
      });
   }

}

前端实现websocket类封装,js,openlayers,geotools,websocket,网络协议,网络

如果对您有帮助

感谢支持技术分享,请点赞支持:

技术合作交流qq:2401315930文章来源地址https://www.toymoban.com/news/detail-788493.html

到了这里,关于前端实现websocket类封装的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSocket的使用方法(JS前端)

    先来一个常用例子 封装的代码 上面的代码就够用,也可以查看我封装好的 WebSocket 代码(包括心跳机制):点击查看 下面详细说明常用的属性和方法 更全面的官网的文档可以去这里看:点击查看 下面是我总结的内容 WebSocket WebSocket 对象提供了用于创建和管理 WebSocket 连接,

    2024年02月02日
    浏览(40)
  • WebSocket心跳机制/服务器端开连接(JS前端)

    情景: 前端使用 WebSocket 的时候,后端长时间没有推送数据,导致 WebSocket 连接经常断开,后端也会报错。 解决方法: 通过 心跳机制 让前端和后端始终保持连接。 代码: 使用方法: 注意: 后端收到以后需要给前端返回数据,否则还是无法保持连接 代码参考了:https://bl

    2024年02月12日
    浏览(38)
  • Flutter:WebSocket封装-实现心跳、重连机制

    前言Permalink Flutter简介 Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Nat

    2024年02月10日
    浏览(52)
  • 前后端接口设计与配置中心系统<二十七>-------前端-管理后台设计实现2【导航架构模块设计与实现、基于react-router-dom实现路由模块、网络模块封装与service层实现】

    在上一次前后端接口设计与配置中心系统二十七-------前端-管理后台设计实现1【基于create-react-app搭建web工程、整合antd与less并搭建具有Ant Design风格的页面、页面结构设计与框架搭建】搭建了前端管理后台的基本框架,接着往下继续开撸,接下来则来搭建一下左侧菜单模块了。

    2023年04月09日
    浏览(45)
  • 前端049_单点登录SSO_封装 Axios 与 Mock.js

    安装 Axios ,来向后台发送接口请求 安装 Axios 发送接口请求 创建 src/utils/request.js

    2024年02月08日
    浏览(103)
  • 前端uniapp封装网络请求详情教程

    1,common文件夹下http.api.js,定义接口 2,common文件夹下http.interceptor.js,请求封装 3,全局数据定义 store文件夹下index.js 注意:vuex的使用前要先导入vuex(npm i vuex),在该方法中还需导入vuex-persistedstate(npm i vuex-persistedstate) 4,main.js中声明(例子中用的比较杂,挑有用的使用) 5,接

    2024年02月02日
    浏览(39)
  • 前端开发---在vue项目中使用openLayers

    本篇文章主要讲解openLayers的初步使用,包括渲染地图、获取点坐标、标记点、中心位置的调整、以及获取到经纬度向后台发送请求 演示地址 官网 gitee链接 npm install ol import “ol/ol.css”; import { Map, View, ol } from “ol”; import TileLayer from “ol/layer/Tile”; DW () { var view = this.map.getVi

    2024年02月08日
    浏览(49)
  • WebSocket原生js实现

    WebSocket 是一种网络通信协议。 1. 简单介绍一下HTTP协议 ​ HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。 通信请求只能由客户端发起,服务端对请求做出应答处理 。 这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消

    2023年04月26日
    浏览(39)
  • Node.js实现WebSocket

    1、Http协议发布REST API 的不足: 每次请求响应完成之后,服务器与客户端之间的连接就断开了,如果客户端想要继续获取服务器的消息,必须再次向服务器发起请 求。这显然无法适应对实时通信有高要求的场景。 2、改善http的不足:Web通信领域出现了一些其他的解决方案,如

    2024年02月02日
    浏览(39)
  • 前端面试:【网络协议与性能优化】HTTP/HTTPS、TCP/IP和WebSocket

    嗨,亲爱的Web开发者!在构建现代Web应用时,了解网络协议是优化性能和确保安全性的关键。本文将深入探讨HTTP/HTTPS、TCP/IP和WebSocket这三个网络协议,帮助你理解它们的作用以及如何优化Web应用的性能。 1. HTTP/HTTPS协议: HTTP(超文本传输协议): HTTP是用于在Web上传输数据的

    2024年02月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包