socket.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. import {
  3. paramsToStr
  4. } from './tools'
  5. class Socket {
  6. constructor(url, data) {
  7. this.connected = false
  8. this.error = false
  9. this.url = `${url}${paramsToStr(data)}`
  10. this.socketTask = {}
  11. this.reconnectLock = true
  12. this.reconnectTimeout = null
  13. this.reconnectNums = 0
  14. // 心跳
  15. this.timeout = 10000
  16. this.clientTimeout = null
  17. this.serverTimeout = null
  18. }
  19. // 允许的订阅
  20. events = {
  21. connect: null,
  22. close: null,
  23. message: null,
  24. error: null,
  25. open: null
  26. }
  27. // 添加订阅
  28. addEvent(type, callback) {
  29. this.events[type] = callback
  30. }
  31. // 触发订阅
  32. dispatch(type, data) {
  33. const fun = this.events[type]
  34. fun && fun(data)
  35. }
  36. connect() {
  37. // 已经连接则无需重复连接
  38. if (this.connected) return
  39. this.dispatch('connect')
  40. this.socketTask = uni.connectSocket({
  41. url: this.url,
  42. complete: () => {}
  43. })
  44. this.socketTask.onOpen(this.onOpen.bind(this))
  45. this.socketTask.onError(this.onError.bind(this));
  46. this.socketTask.onMessage(this.onMessage.bind(this))
  47. this.socketTask.onClose(this.onClose.bind(this));
  48. }
  49. close() {
  50. this.reconnectLock = false
  51. clearTimeout(this.clientTimeout)
  52. clearTimeout(this.serverTimeout)
  53. this.socketTask.close && this.socketTask.close()
  54. }
  55. reconnect() {
  56. if (!this.reconnectLock) {
  57. return
  58. }
  59. // 重连次数过多,断开不重连
  60. if (this.reconnectNums >= 5) {
  61. return
  62. }
  63. this.reconnectNums++
  64. this.reconnectLock = false
  65. // 延迟重连请求过多
  66. clearTimeout(this.reconnectTimeout)
  67. this.reconnectTimeout = setTimeout(() => {
  68. this.connect()
  69. this.reconnectLock = true
  70. }, 4000)
  71. }
  72. start() {
  73. clearTimeout(this.clientTimeout)
  74. clearTimeout(this.serverTimeout)
  75. this.clientTimeout = setTimeout(() => {
  76. this.send({
  77. event: 'ping'
  78. })
  79. this.serverTimeout = setTimeout(() => {
  80. this.socketTask.close()
  81. }, this.timeout)
  82. }, this.timeout)
  83. }
  84. reset() {
  85. this.reconnectNums = 0
  86. this.start()
  87. }
  88. send(data) {
  89. // 如果socket已连接则发送消息
  90. if (!this.connected) {
  91. return
  92. }
  93. let datas = JSON.stringify(data)
  94. // console.log('发送信息:' + datas)
  95. this.socketTask.send({
  96. data: datas,
  97. })
  98. }
  99. onOpen() {
  100. this.connected = true
  101. // 开启心跳
  102. this.start()
  103. // console.log('连接成功')
  104. this.dispatch('open')
  105. }
  106. onError(res) {
  107. this.error = true
  108. this.connected = false
  109. this.dispatch('error')
  110. // console.log('连接错误', res)
  111. }
  112. onMessage({data}) {
  113. this.dispatch('message', JSON.parse(data))
  114. // console.log('收到信息:', data)
  115. // 重置心跳
  116. this.reset()
  117. }
  118. onClose(res) {
  119. this.dispatch('close')
  120. // console.log('连接已关闭', res)
  121. this.connected = false
  122. this.reconnect()
  123. }
  124. }
  125. export default Socket