1- import { Channel } from "./Channel" ;
2- import { AxiosResponse } from "axios" ;
1+ import { AxiosResponse } from "axios" ;
2+ import axios from 'axios' ;
3+ import { Channel } from "./Channel" ;
4+
5+ export type Options = { authEndpoint : string , host : string , bearerToken : string , auth : any , debug : boolean } ;
36
4- export type Options = { authEndpoint : string , host : string , bearerToken : string , auth : any } ;
57export type MessageBody = { event : string , channel ?: string , data : object } ;
68
79export class Websocket {
@@ -19,14 +21,20 @@ export class Websocket {
1921
2022 private socketId : string ;
2123
24+ private closing = false ;
25+
2226 private pingInterval : NodeJS . Timeout ;
2327
24- constructor ( options : Options ) {
25- this . options = options ;
28+ private connect ( host : string ) : void {
29+ this . options . debug && console . log ( 'Connecting' ) ;
2630
27- this . websocket = new WebSocket ( options . host )
31+ this . websocket = new WebSocket ( host )
2832
2933 this . websocket . onopen = ( ) => {
34+ this . send ( {
35+ event : 'whoami' ,
36+ } )
37+
3038 while ( this . buffer . length ) {
3139 const message = this . buffer [ 0 ]
3240
@@ -44,7 +52,7 @@ export class Websocket {
4452 }
4553
4654 if ( message . channel ) {
47- console . log ( `Received event ${ message . event } on channel ${ message . channel } ` )
55+ this . options . debug && console . log ( `Received event ${ message . event } on channel ${ message . channel } ` )
4856
4957 if ( this . listeners [ message . channel ] && this . listeners [ message . channel ] [ message . event ] ) {
5058 this . listeners [ message . channel ] [ message . event ] ( message . data )
@@ -56,12 +64,24 @@ export class Websocket {
5664 if ( this . internalListeners [ message . event ] ) {
5765 this . internalListeners [ message . event ] ( message . data )
5866 }
67+
5968 }
6069
70+
71+ this . websocket . onclose = ( ) => {
72+ if ( this . socketId && ! this . closing || ! this . socketId ) {
73+ this . options . debug && console . info ( 'Connection lost, reconnecting...' ) ;
74+ setTimeout ( ( ) => {
75+ this . socketId = undefined
76+ this . connect ( host )
77+ } , 1000 ) ;
78+ }
79+ } ;
80+
6181 this . on ( 'whoami' , ( { socket_id : socketId } ) => {
6282 this . socketId = socketId
6383
64- console . log ( `just set socketId to ${ socketId } ` )
84+ this . options . debug && console . log ( `just set socketId to ${ socketId } ` )
6585
6686 while ( this . channelBacklog . length ) {
6787 const channel = this . channelBacklog [ 0 ]
@@ -72,27 +92,32 @@ export class Websocket {
7292 }
7393 } )
7494
75- this . send ( {
76- event : 'whoami' ,
77- } )
7895
7996 // send ping every 60 seconds to keep connection alive
8097 this . pingInterval = setInterval ( ( ) => {
81- console . log ( 'Sending ping' )
82-
83- this . send ( {
84- event : 'ping' ,
85- } )
98+ if ( this . websocket . readyState === this . websocket . OPEN ) {
99+ this . options . debug && console . log ( 'Sending ping' )
100+ this . send ( {
101+ event : 'ping' ,
102+ } )
103+ }
86104 } , 60 * 1000 )
87105
106+ }
107+
108+ constructor ( options : Options ) {
109+ this . options = options ;
110+
111+ this . connect ( this . options . host ) ;
112+
88113 return this
89114 }
90115
91116 protected parseMessage ( body : string ) : MessageBody {
92117 try {
93118 return JSON . parse ( body )
94119 } catch ( error ) {
95- console . error ( error )
120+ this . options . debug && console . error ( error )
96121
97122 return undefined
98123 }
@@ -115,7 +140,8 @@ export class Websocket {
115140 this . buffer . push ( message )
116141 }
117142
118- close ( ) : void {
143+ close ( ) : void {
144+ this . closing = true
119145 this . internalListeners = { }
120146
121147 clearInterval ( this . pingInterval )
@@ -134,7 +160,7 @@ export class Websocket {
134160
135161 private actuallySubscribe ( channel : Channel ) : void {
136162 if ( channel . name . startsWith ( 'private-' ) || channel . name . startsWith ( 'presence-' ) ) {
137- console . log ( `Sending auth request for channel ${ channel . name } ` )
163+ this . options . debug && console . log ( `Sending auth request for channel ${ channel . name } ` )
138164
139165 if ( this . options . bearerToken ) {
140166 this . options . auth . headers [ 'Authorization' ] = 'Bearer ' + this . options . bearerToken ;
@@ -146,21 +172,21 @@ export class Websocket {
146172 } , {
147173 headers : this . options . auth . headers || { }
148174 } ) . then ( ( response : AxiosResponse ) => {
149- console . log ( `Subscribing to channels ${ channel . name } ` )
175+ this . options . debug && console . log ( `Subscribing to channels ${ channel . name } ` )
150176
151177 this . send ( {
152178 event : 'subscribe' ,
153179 data : {
154180 channel : channel . name ,
155- ... response . data
181+ ...response . data
156182 } ,
157183 } )
158184 } ) . catch ( ( error ) => {
159- console . log ( `Auth request for channel ${ channel . name } failed` )
160- console . error ( error )
185+ this . options . debug && console . log ( `Auth request for channel ${ channel . name } failed` )
186+ this . options . debug && console . error ( error )
161187 } )
162188 } else {
163- console . log ( `Subscribing to channels ${ channel . name } ` )
189+ this . options . debug && console . log ( `Subscribing to channels ${ channel . name } ` )
164190
165191 this . send ( {
166192 event : 'subscribe' ,
0 commit comments