useSSE.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import type { SSEvent } from 'sse.js'
  2. import { SSE } from 'sse.js'
  3. import { onUnmounted, shallowRef } from 'vue'
  4. export interface SSEOptions {
  5. url: string
  6. token: string
  7. onMessage?: (data: any) => void
  8. onError?: () => void
  9. parseData?: boolean
  10. reconnectInterval?: number
  11. }
  12. /**
  13. * SSE Composable
  14. * Provide the ability to create, manage, and automatically clean up SSE connections
  15. */
  16. export function useSSE() {
  17. const sseInstance = shallowRef<SSE>()
  18. /**
  19. * Connect to SSE service
  20. */
  21. function connect(options: SSEOptions) {
  22. disconnect()
  23. const {
  24. url,
  25. token,
  26. onMessage,
  27. onError,
  28. parseData = true,
  29. reconnectInterval = 5000,
  30. } = options
  31. const sse = new SSE(url, {
  32. headers: {
  33. Authorization: token,
  34. },
  35. })
  36. // Handle messages
  37. sse.onmessage = (e: SSEvent) => {
  38. if (!e.data) {
  39. return
  40. }
  41. try {
  42. const parsedData = parseData ? JSON.parse(e.data) : e.data
  43. onMessage?.(parsedData)
  44. }
  45. catch (error) {
  46. console.error('Error parsing SSE message:', error)
  47. }
  48. }
  49. // Handle errors and reconnect
  50. sse.onerror = () => {
  51. onError?.()
  52. // Reconnect logic
  53. setTimeout(() => {
  54. connect(options)
  55. }, reconnectInterval)
  56. }
  57. sseInstance.value = sse
  58. return sse
  59. }
  60. /**
  61. * Disconnect SSE connection
  62. */
  63. function disconnect() {
  64. if (sseInstance.value) {
  65. sseInstance.value.close()
  66. sseInstance.value = undefined
  67. }
  68. }
  69. // Automatically disconnect when the component is unmounted
  70. onUnmounted(() => {
  71. disconnect()
  72. })
  73. return {
  74. connect,
  75. disconnect,
  76. sseInstance,
  77. }
  78. }