1+ import Gleap , { GleapFrameManager , GleapMetaDataManager , GleapSession } from "./Gleap" ;
12import { gleapDataParser } from "./GleapHelper" ;
2- import Gleap , { GleapSession , GleapNotificationManager , GleapMetaDataManager , GleapFrameManager } from "./Gleap" ;
33
44export default class GleapStreamedEvent {
55 eventArray = [ ] ;
@@ -8,8 +8,15 @@ export default class GleapStreamedEvent {
88 errorCount = 0 ;
99 streamingEvents = false ;
1010 lastUrl = undefined ;
11- stopped = false ;
1211 mainLoopTimeout = null ;
12+ socket = null ;
13+ connectedWebSocketGleapId = null ;
14+ connectionTimeout = null ;
15+ pingWS = null ;
16+ handleOpenBound = null ;
17+ handleErrorBound = null ;
18+ handleMessageBound = null ;
19+ handleCloseBound = null ;
1320
1421 // GleapStreamedEvent singleton
1522 static instance ;
@@ -22,14 +29,99 @@ export default class GleapStreamedEvent {
2229 }
2330 }
2431
25- constructor ( ) { }
32+ constructor ( ) {
33+ this . handleOpenBound = this . handleOpen . bind ( this ) ;
34+ this . handleErrorBound = this . handleError . bind ( this ) ;
35+ this . handleMessageBound = this . handleMessage . bind ( this ) ;
36+ this . handleCloseBound = this . handleClose . bind ( this ) ;
37+ }
38+
39+ cleanupWebSocket ( ) {
40+ if ( this . connectionTimeout ) {
41+ clearTimeout ( this . connectionTimeout ) ;
42+ this . connectionTimeout = null ;
43+ }
44+
45+ if ( this . pingWS ) {
46+ clearInterval ( this . pingWS ) ;
47+ }
48+
49+ if ( this . socket ) {
50+ this . socket . removeEventListener ( 'open' , this . handleOpenBound ) ;
51+ this . socket . removeEventListener ( 'error' , this . handleErrorBound ) ;
52+ this . socket . removeEventListener ( 'message' , this . handleMessageBound ) ;
53+ this . socket . removeEventListener ( 'close' , this . handleCloseBound ) ;
54+ this . socket . close ( ) ;
55+ this . socket = null ;
56+ }
57+ }
58+
59+ initWebSocket ( ) {
60+ this . cleanupWebSocket ( ) ;
61+
62+ this . connectedWebSocketGleapId = GleapSession . getInstance ( ) . session . gleapId ;
63+
64+ if ( ! GleapSession . getInstance ( ) . session || ! GleapSession . getInstance ( ) . sdkKey ) {
65+ return ;
66+ }
67+
68+ this . socket = new WebSocket ( `${ GleapSession . getInstance ( ) . wsApiUrl } ?gleapId=${ GleapSession . getInstance ( ) . session . gleapId } &gleapHash=${ GleapSession . getInstance ( ) . session . gleapHash } &apiKey=${ GleapSession . getInstance ( ) . sdkKey } &sdkVersion=${ SDK_VERSION } ` ) ;
69+ this . socket . addEventListener ( 'open' , this . handleOpenBound ) ;
70+ this . socket . addEventListener ( 'message' , this . handleMessageBound ) ;
71+ this . socket . addEventListener ( 'error' , this . handleErrorBound ) ;
72+ this . socket . addEventListener ( 'close' , this . handleCloseBound ) ;
73+ }
74+
75+ handleOpen ( event ) {
76+ this . pingWS = setInterval ( ( ) => {
77+ if ( this . socket . readyState === this . socket . OPEN ) {
78+ this . socket . send ( JSON . stringify ( {
79+ name : 'ping' ,
80+ data : { } ,
81+ } ) ) ;
82+ }
83+ } , 30000 ) ;
84+
85+ if ( this . connectionTimeout ) {
86+ clearTimeout ( this . connectionTimeout ) ;
87+ this . connectionTimeout = null ;
88+ }
89+ }
90+
91+ handleMessage ( event ) {
92+ this . processMessage ( JSON . parse ( event . data ) ) ;
93+ }
94+
95+ handleError ( error ) { }
96+
97+ handleClose ( event ) {
98+ setTimeout ( ( ) => {
99+ this . initWebSocket ( ) ;
100+ } , 5000 ) ;
101+ }
102+
103+ processMessage ( message ) {
104+ try {
105+ if ( message . name === 'update' ) {
106+ const { a, u } = message . data ;
107+ if ( ! GleapFrameManager . getInstance ( ) . isOpened ( ) ) {
108+ if ( a ) {
109+ Gleap . getInstance ( ) . performActions ( a ) ;
110+ }
111+ if ( u != null ) {
112+ GleapNotificationManager . getInstance ( ) . setNotificationCount ( u ) ;
113+ }
114+ }
115+ }
116+ } catch ( exp ) { }
117+ }
26118
27119 getEventArray ( ) {
28120 return this . eventArray ;
29121 }
30122
31123 stop ( ) {
32- this . stopped = true ;
124+ this . cleanupMainLoop ( ) ;
33125 }
34126
35127 resetErrorCountLoop ( ) {
@@ -38,18 +130,25 @@ export default class GleapStreamedEvent {
38130 } , 60000 ) ;
39131 }
40132
41- restart ( ) {
133+ cleanupMainLoop ( ) {
42134 if ( this . mainLoopTimeout ) {
43135 clearInterval ( this . mainLoopTimeout ) ;
44136 this . mainLoopTimeout = null ;
45137 }
138+ }
139+
140+ restart ( ) {
141+ // Only reconnect websockets when needed.
142+ if ( this . connectedWebSocketGleapId !== GleapSession . getInstance ( ) . session . gleapId ) {
143+ this . initWebSocket ( ) ;
144+ }
46145
146+ this . cleanupMainLoop ( ) ;
47147 this . trackInitialEvents ( ) ;
48148 this . runEventStreamLoop ( ) ;
49149 }
50150
51151 start ( ) {
52- this . stopped = false ;
53152 this . startPageListener ( ) ;
54153 this . resetErrorCountLoop ( ) ;
55154 }
@@ -76,9 +175,6 @@ export default class GleapStreamedEvent {
76175 startPageListener ( ) {
77176 const self = this ;
78177 setInterval ( function ( ) {
79- if ( self . stopped ) {
80- return ;
81- }
82178 self . logCurrentPage ( ) ;
83179 } , 1000 ) ;
84180 }
@@ -106,28 +202,32 @@ export default class GleapStreamedEvent {
106202 }
107203
108204 runEventStreamLoop = ( ) => {
109- if ( this . stopped ) {
110- return ;
111- }
112-
113205 const self = this ;
114206 this . streamEvents ( ) ;
115207
116208 this . mainLoopTimeout = setTimeout ( function ( ) {
117209 self . runEventStreamLoop ( ) ;
118- } , 10000 ) ;
210+ } , 2000 ) ;
119211 } ;
120212
121213 streamEvents = ( ) => {
122214 if ( ! GleapSession . getInstance ( ) . ready || this . streamingEvents || this . errorCount > 2 ) {
123215 return ;
124216 }
125217
218+ // Nothing to stream.
219+ if ( this . streamedEventArray . length === 0 ) {
220+ return ;
221+ }
222+
223+ // Sockets not connected.
224+ if ( ! this . socket || this . socket . readyState !== this . socket . OPEN ) {
225+ return ;
226+ }
227+
126228 const self = this ;
127229 this . streamingEvents = true ;
128230
129- const preGleapId = GleapSession . getInstance ( ) . getGleapId ( ) ;
130-
131231 const http = new XMLHttpRequest ( ) ;
132232 http . open ( "POST" , GleapSession . getInstance ( ) . apiUrl + "/sessions/ping" ) ;
133233 http . setRequestHeader ( "Content-Type" , "application/json;charset=UTF-8" ) ;
@@ -140,22 +240,6 @@ export default class GleapStreamedEvent {
140240 if ( http . readyState === 4 ) {
141241 if ( http . status === 200 || http . status === 201 ) {
142242 self . errorCount = 0 ;
143-
144- // Only perform actions if gleapId was not changed.
145- if ( GleapSession . getInstance ( ) . getGleapId ( ) === preGleapId ) {
146- try {
147- const response = JSON . parse ( http . responseText ) ;
148- const { a, u } = response ;
149- if ( ! GleapFrameManager . getInstance ( ) . isOpened ( ) ) {
150- if ( a ) {
151- Gleap . getInstance ( ) . performActions ( a ) ;
152- }
153- if ( u != null ) {
154- GleapNotificationManager . getInstance ( ) . setNotificationCount ( u ) ;
155- }
156- }
157- } catch ( exp ) { }
158- }
159243 } else {
160244 self . errorCount ++ ;
161245 }
@@ -171,6 +255,7 @@ export default class GleapStreamedEvent {
171255 events : this . streamedEventArray ,
172256 opened : GleapFrameManager . getInstance ( ) . isOpened ( ) ,
173257 sdkVersion : SDK_VERSION ,
258+ ws : true ,
174259 } )
175260 ) ;
176261
0 commit comments