资讯专栏INFORMATION COLUMN

tradingView-webSocket进阶——Vue.js

levius / 3337人阅读

摘要:无奈,还是需要对这份代码进行加工。功能缺少,主要指业务逻辑实现上的功能缺少。缺少的功能主要是历史记录获取展示的功能。查询缓存是否为空,如果为空,表示数据还没有下发,后再查询一次。如果有数据,取到当前数据,执行回调。

前几天写了一篇关于tradingView和webSocket的文章传送门,因为代码本身还在整合中,所以比较混乱,而且也没有demo可以运行。
这两天在GitHub上面看到了一个vue写的demo,仔细对比,原来就是我得到的最初版本的tradingView-webSocket代码,很开心,以为可以直接嵌入项目中,省了一番功夫。
然而现实是骨感的,这个demo并没有写的太完善,该缺的功能一样还是缺着的……传送门。

无奈,还是需要对这份代码进行加工。

1、原demo分析

核心代码有4个文件:

index.vue

datafees.js

dataUpdater.js

scoket.js

index是tradingView的实例化和用户行为的响应,属于业务逻辑实现。
datafees定义了实例化tradingview的对象,提供图表调用的方法,属于数据交互的接口。
dataUpdater是一个数据的触发器,当数据发生变化,通过dataUpdater来通知tradingview进行图表渲染,是业务逻辑和tradingview实例之间的通信人。
scoket定义了webSocket的连接方式和数据收发的方法,是前后端数据交互的实现。

功能缺少,主要指业务逻辑实现上的功能缺少。
缺少的功能主要是历史记录获取、展示的功能。
初始化即获取1440条数据渲染到界面上,增量数据(实时交易记录)直接覆盖第1440条记录。
这样做的结果是,用户往左边拖拽的时候,不能展示更多的数据,同时,最新的增量数据的展示也是错位的。
另外,没有对webSocket的close事件进行监听,当连接关闭之后,增量更新即停止,这样的用户体验是不够的。
而且,初始化即获取1440条记录,将会导致初始化的时候需要请求的数据过多,查询时间和数据接收的时间都受影响,同样影响用户体验。

2、index.vue详解

index.vue

</>复制代码

  1. created(){
  2. this.socket.doOpen()
  3. this.socket.on("open", () => {
  4. this.socket.send({ cmd: "req", args: [`candle.M5.btcusdt}`, 1440, parseInt(Date.now() / 1000)] })
  5. })
  6. this.socket.on("message", this.onMessage)
  7. }

在创建之后,连接socket,发送历史数据请求,从当前时间往回获取1440条数据,获取的是5分钟时间颗粒的btcusdt商品。然后监听从webSocket返回的数据。

实例化tradingview:

</>复制代码

  1. init(){}

通过webSocket发送数据:

</>复制代码

  1. sendMessage(){}

订阅实时交易数据:

</>复制代码

  1. subscribe(){}

取消订阅实时交易数据:

</>复制代码

  1. unSubscribe(){}

以上方法,都是直接调用接口,下面是业务逻辑:

</>复制代码

  1. onMessage(data) {
  2. // console.log(data)
  3. if (data.data && data.data.length) {
  4. const list = []
  5. const ticker = `${this.symbol}-${this.interval}`
  6. data.data.forEach(function (element) {
  7. list.push({
  8. time: this.interval !== "D" || this.interval !== "1D" ? element.id * 1000 : element.id,
  9. open: element.open,
  10. high: element.high,
  11. low: element.low,
  12. close: element.close,
  13. volume: element.quote_vol
  14. })
  15. }, this)
  16. this.cacheData[ticker] = list
  17. this.lastTime = list[list.length - 1].time
  18. this.subscribe()
  19. }
  20. if (data.type && data.type.indexOf(this.symbol.toLowerCase()) !== -1) {
  21. // console.log(" >> sub:", data.type)
  22. this.datafeeds.barsUpdater.updateData()
  23. const ticker = `${this.symbol}-${this.interval}`
  24. const barsData = {
  25. time: data.id * 1000,
  26. open: data.open,
  27. high: data.high,
  28. low: data.low,
  29. close: data.close,
  30. volume: data.quote_vol
  31. }
  32. if (barsData.time >= this.lastTime && this.cacheData[ticker] && this.cacheData[ticker].length) {
  33. this.cacheData[ticker][this.cacheData[ticker].length - 1] = barsData
  34. }
  35. }
  36. }

从socket接到数据,判断数据类型,如果是数组,代表的是历史数据,存入cacheData,记录时间,开始订阅增量数据。
如果不是数组,而且有type属性,代表的是增量数据,通知图表插件渲染数据,替换cacheData的最后一个元素。

下面的方法,是图表插件查询数据的时候使用:

</>复制代码

  1. getBars(symbolInfo, resolution, rangeStartDate, rangeEndDate, onLoadedCallback) {
  2. // console.log(" >> :", rangeStartDate, rangeEndDate)
  3. if (this.interval !== resolution) {
  4. this.unSubscribe(this.interval)
  5. this.interval = resolution
  6. if (resolution < 60) {
  7. this.sendMessage({ cmd: "req", args: [`candle.M${this.interval}.${this.symbol.toLowerCase()}`, 1440, parseInt(Date.now() / 1000)] })
  8. } else if (resolution >= 60) {
  9. this.sendMessage({ cmd: "req", args: [`candle.H${this.interval / 60}.${this.symbol.toLowerCase()}`, 1440, parseInt(Date.now() / 1000)] })
  10. } else {
  11. this.sendMessage({ cmd: "req", args: [`candle.D1.${this.symbol.toLowerCase()}`, 800, parseInt(Date.now() / 1000)] })
  12. }
  13. }
  14. const ticker = `${this.symbol}-${this.interval}`
  15. if (this.cacheData[ticker] && this.cacheData[ticker].length) {
  16. this.isLoading = false
  17. const newBars = []
  18. this.cacheData[ticker].forEach(item => {
  19. if (item.time >= rangeStartDate * 1000 && item.time <= rangeEndDate * 1000) {
  20. newBars.push(item)
  21. }
  22. })
  23. onLoadedCallback(newBars)
  24. } else {
  25. const self = this
  26. this.getBarTimer = setTimeout(function () {
  27. self.getBars(symbolInfo, resolution, rangeStartDate, rangeEndDate, onLoadedCallback)
  28. }, 10)
  29. }
  30. }

如果图表插件查询的时候,resolution不同,则表示用户切换了时间颗粒,需要取消订阅,修改interval,重新获取历史记录。
查询缓存cacheData是否为空,如果为空,表示数据还没有下发,10ms后再查询一次。
如果cacheData有数据,取到当前数据,执行回调onLoadedCallback。

3、结尾

如上,代码已经分析完了,至于怎么修改,未完待续!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99275.html

相关文章

  • tradingview-websocket进阶

    摘要:用户量量大,数据量大,而且要求实时更新数据的时候,需要使用。该方法接收的有两种,一种是数组。是历史数据,时间段的数据,根据时间颗粒来划分。 1、websocket 用户量量大,数据量大,而且要求实时更新数据的时候,需要使用websocket。tradingview正好就是这样的应用场景。 2、tradingview和websocket结合 getBars方法。tradingview图...

    Cc_2011 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    sutaking 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    khs1994 评论0 收藏0
  • 走进Vue时代进阶篇(01):重构电商购物车模块

    摘要:欢迎你们跟着闰土大叔走进时代。其中购买数量可以增加或减少,每类商品还可以从购物车中移除。后记这大概就是一次用重构电商项目中的购物车模块的所有实现过程。作者闰土大叔链接来源掘金著作权归作者所有。 前言 从这篇文章开始,我准备给大家分享一些关于Vue.js这门框架的技巧性系列文章,正好我们公司项目中也用到了Vue。所以,教是最好的学。进阶篇比较适合于二三线城市,还在小厂打拼的童鞋们。欢迎你...

    kk_miles 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<