ws.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { Stomp } from './stomp.js'
  2. import UniWebSocket from './uniWebSocket.js'
  3. /**
  4. * WebSocket stomp 实例
  5. */
  6. class Ws {
  7. constructor() {
  8. // 重连间隔
  9. this.reconnectInterval = 10000
  10. // 是否打印debug信息
  11. this.debug = true
  12. // ws地址
  13. this.url = ''
  14. // stomp实例
  15. this.client = null
  16. // 重连事件编号
  17. this.reconnectId = null
  18. // 订阅集合
  19. this.subscribes = {}
  20. }
  21. /**
  22. * 创建连接
  23. */
  24. connect(wsUrl,success,fail) {
  25. this.url=wsUrl;
  26. debugger
  27. // 如已存在连接则不创建
  28. if (this.client && this.client.connected) {
  29. return
  30. }
  31. // 创建连接,认证token以第二个参数:Sec-WebSocket-Protocol传递到后台,后台需将此头信息原样返回
  32. // 注:如不想在此处进行认证,可考虑在下面的client.connect方法中传递header进行认证
  33. // 从缓存中获取token
  34. //let token = uni.getStorageSync('AccessToken')
  35. //let ws = new UniWebSocket(this.url, [token])
  36. let ws = new UniWebSocket(this.url)
  37. this.client = Stomp.over(ws)
  38. // 控制是否打印debug信息
  39. if (!this.debug) {
  40. this.client.debug = () => {}
  41. }
  42. this.client.connect({},
  43. frame => {
  44. // 初始化订阅
  45. Object.keys(this.subscribes).forEach(key => {
  46. this.subscribe(key, this.subscribes[key].callback)
  47. })
  48. if(success){
  49. success(frame);
  50. }
  51. },
  52. error => {
  53. // 重连
  54. this.reconnectId = setTimeout(() => {
  55. this.reconnect()
  56. }, this.reconnectInterval)
  57. if(fail){
  58. fail(error);
  59. }
  60. }
  61. )
  62. // 监听WebSocket对象连接状态,如失败,则stomp的connect回调不会触发,应在此重连
  63. ws.onerror = () => {
  64. // 重连
  65. this.reconnectId = setTimeout(() => {
  66. // 刷新token
  67. refreshToken().then(() => {
  68. this.reconnect()
  69. })
  70. }, this.reconnectInterval)
  71. }
  72. }
  73. /**
  74. * 重新连接
  75. */
  76. reconnect() {
  77. // 订阅状态置false
  78. Object.keys(this.subscribes).forEach(key => {
  79. this.subscribes[key]['subscribed'] = false
  80. })
  81. // 连接
  82. this.connect()
  83. }
  84. /**
  85. * 断开连接
  86. */
  87. disconnect() {
  88. // 断开连接
  89. if (this.client) {
  90. this.client.disconnect()
  91. }
  92. // 停止重连事件
  93. if (this.reconnectId) {
  94. clearTimeout(this.reconnectId)
  95. this.reconnectId = null
  96. }
  97. // 清空所有除订阅缓存
  98. this.subscribes = {}
  99. }
  100. /**
  101. * 订阅
  102. * @param {Object} destination 主题
  103. * @param {Object} callback 回调
  104. */
  105. subscribe(destination, callback) {
  106. if (this.subscribes[destination] && this.subscribes[destination]['subscribed']) { // 已订阅
  107. return
  108. } else if (this.client && this.client.connected) { // 已连接:调用订阅,缓存订阅信息
  109. console.log('已连接,发起订阅')
  110. let subscribe = this.client.subscribe(destination, res => callback(res))
  111. this.subscribes[destination] = { callback: callback, subscribed: true, subscribe: subscribe }
  112. } else { // 未连接:缓存订阅信息
  113. this.subscribes[destination] = { callback: callback, subscribed: false }
  114. }
  115. }
  116. /**
  117. * 取消订阅
  118. * @param {Object} destination 主题
  119. */
  120. unsubscribe(destination) {
  121. if (this.subscribes[destination]) {
  122. // 取消订阅
  123. this.subscribes[destination].subscribe.unsubscribe()
  124. // 删除订阅缓存
  125. delete this.subscribes[destination]
  126. }
  127. }
  128. /**
  129. * 向服务器发送消息
  130. * @param {Object} destination 主题
  131. * @param {Object} message 消息内容
  132. */
  133. send(destination, message) {
  134. if (this.client) {
  135. this.client.send(destination, null, message)
  136. }
  137. }
  138. }
  139. export default new Ws()