signalR.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio
  2. import * as signalR from '@microsoft/signalr';
  3. import { Cookie, Local } from '@/utils/storage';
  4. import { submitLog } from '@/api/public/log';
  5. import { getNowDateTime } from '@/utils/constants';
  6. // 记录日志
  7. const submitLogFn = async (request: any) => {
  8. try {
  9. await submitLog(request);
  10. } catch (error) {
  11. console.log(error);
  12. }
  13. };
  14. export default {
  15. // signalR对象
  16. SR: null as any,
  17. // 失败连接重试次数
  18. failNum: 99,
  19. baseUrl: import.meta.env.VITE_API_SOCKET_URL,
  20. init() {
  21. const token = Cookie.get('token');
  22. const connection = new signalR.HubConnectionBuilder()
  23. .withUrl(this.baseUrl, { accessTokenFactory: () => token, skipNegotiation: true, transport: 1 })
  24. .withAutomaticReconnect() //自动重新连接
  25. .configureLogging(signalR.LogLevel.Warning)
  26. .build();
  27. this.SR = connection;
  28. // 断线重连
  29. connection.onclose(async () => {
  30. const name: string = `业务系统的websocket断开链接`;
  31. const remark: string = `业务系统的websocket断开链接`;
  32. const request = {
  33. creationTime: new Date(),
  34. name,
  35. remark,
  36. executeUrl: import.meta.env.VITE_API_SOCKET_URL,
  37. };
  38. await submitLogFn(request);
  39. console.log('业务系统signal当前链接状态:', connection.state, getNowDateTime());
  40. // 建议用户重新刷新浏览器
  41. await this.start();
  42. });
  43. connection.onreconnected(async () => {
  44. const name: string = `业务系统websocket断线重连成功`;
  45. const remark: string = `业务系统websocket断线重连成功`;
  46. const request = {
  47. creationTime: new Date(),
  48. name,
  49. remark,
  50. executeUrl: import.meta.env.VITE_API_SOCKET_URL,
  51. };
  52. await submitLogFn(request);
  53. console.log('业务系统signal断线重连成功', getNowDateTime());
  54. // location.reload();
  55. /*ElNotification({
  56. type: 'success',
  57. title: '提示',
  58. message: `断线重连成功`,
  59. });*/
  60. });
  61. // 服务端推送消息
  62. connection.on('Send', (message: any) => {
  63. console.log(`有用户加入分组:${message}`, getNowDateTime());
  64. });
  65. // 服务端推送消息
  66. connection.on('CircularRecord', (message: any) => {
  67. console.log(`小红点消息:${message}`, getNowDateTime());
  68. });
  69. // 服务端推送消息
  70. connection.on('SeatState', (message: any) => {
  71. console.log(`座席状态:${JSON.stringify(message)}`, getNowDateTime());
  72. });
  73. // 服务端推送消息
  74. connection.on('RestApplyPass', (message: any) => {
  75. console.log(`休息申请通过:${message}`);
  76. });
  77. // 服务端推送消息
  78. connection.on('ToDayWaitNum', (message: any) => {
  79. // console.log(`今日等待:${message}`);
  80. });
  81. // 服务端推送消息
  82. connection.on('CurrentWaitNum', (message: any) => {
  83. // console.log(`当前等待:${message}`);
  84. });
  85. // 服务端推送消息
  86. connection.on('BsSeatStateDataShowArea1', (message: any) => {});
  87. // 服务端推送消息
  88. connection.on('BsSeatStateDataShowArea2', (message: any) => {});
  89. // 服务端推送消息
  90. connection.on('BsSeatStateDataShowArea3', (message: any) => {});
  91. // 服务端推送消息
  92. connection.on('BsSeatStateDataShowArea4', (message: any) => {});
  93. },
  94. /**
  95. * @description 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")})
  96. * state Connected 已连接 Connecting 正在连接 Disconnected 断开连接 Reconnecting 正在重新连接
  97. * @returns
  98. */
  99. async start() {
  100. try {
  101. //使用async和await 或 promise的then 和catch 处理来自服务端的异常
  102. await this.SR.start();
  103. console.log('业务系统signal当前链接状态:', this.SR.state, getNowDateTime());
  104. const name: string = `业务系统的websocket链接成功`;
  105. const remark: string = `业务系统的websocket断开链接`;
  106. const request = {
  107. creationTime: new Date(),
  108. name,
  109. remark,
  110. executeUrl: import.meta.env.VITE_API_SOCKET_URL,
  111. };
  112. await submitLogFn(request);
  113. return Promise.resolve();
  114. } catch (error: any) {
  115. this.failNum--;
  116. if (this.failNum > 0 && this.SR?.state === 'Disconnected') {
  117. //断开链接重新链接
  118. /*ElNotification({
  119. type: 'warning',
  120. title: '提示',
  121. message: `断开连接了,正在重连, 剩余自动重连次数${this.failNum} 次,如未重连成功,请刷新浏览器重试`,
  122. });*/
  123. setTimeout(async () => {
  124. await this.SR?.start();
  125. }, 5000);
  126. }
  127. return Promise.reject(error);
  128. }
  129. },
  130. /**
  131. * @description 加入分组
  132. * @param groupName string 分组名称
  133. * @params {string} CallCenter 呼叫中心
  134. * @params BigScreenDataShow 大屏数据展示
  135. * @returns
  136. */
  137. async joinGroup(groupName: string) {
  138. if (this.SR?.state === 'Connected') {
  139. // 判断是否已经建立链接 如果没有 先链接
  140. await this.SR.invoke('JoinGroupAsync', { GroupName: groupName });
  141. } else {
  142. try {
  143. await this.start();
  144. setTimeout(async () => {
  145. await this.SR?.invoke('JoinGroupAsync', { GroupName: groupName });
  146. }, 500);
  147. } catch (err) {
  148. console.log(err);
  149. }
  150. }
  151. },
  152. /**
  153. * @description 离开分组
  154. * @param groupName string
  155. * @params CallCenter 呼叫中心
  156. * @params BigScreenDataShow 大屏数据展示
  157. * @returns
  158. */
  159. async leaveGroup(groupName: string) {
  160. if (this.SR.state === 'Connected') {
  161. // 判断是否已经建立链接 如果没有 先链接
  162. await this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
  163. } else {
  164. // 等待链接成功再发送
  165. if (this.SR.state === 'Connecting') {
  166. setTimeout(async () => {
  167. await this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
  168. }, 500);
  169. return;
  170. }
  171. await this.start()
  172. .then(async () => {
  173. setTimeout(async () => {
  174. await this.SR.invoke('LeaveGroupAsync', { GroupName: groupName });
  175. }, 500);
  176. })
  177. .catch((err) => {
  178. console.log(err);
  179. });
  180. }
  181. },
  182. /**
  183. * @description 关闭链接
  184. * @returns
  185. */
  186. async stop() {
  187. try {
  188. //使用async和await 或 promise的then 和catch 处理来自服务端的异常
  189. await this.SR.stop();
  190. console.log(this.SR.state, '断开链接', getNowDateTime());
  191. } catch (error) {
  192. console.log('signalR', error);
  193. }
  194. },
  195. /**
  196. * @description 离开所有分组并且关闭链接
  197. * @returns
  198. */
  199. async leaveAllGroupAndStop() {
  200. try {
  201. const telStatusInfo = Local.get('telStatusInfo');
  202. //使用async和await 或 promise的then 和catch 处理来自服务端的异常
  203. await this.leaveGroup('CallCenter');
  204. await this.leaveGroup('BigScreen-SeatState');
  205. await this.stop();
  206. console.log(this.SR.state, '断开链接', getNowDateTime());
  207. } catch (error) {
  208. console.log('signalR', error);
  209. }
  210. },
  211. };