@@ -5,6 +5,7 @@ import emitter, * as E from 'utils/emitter'
55import config from 'config'
66import { autorun , runInAction } from 'mobx'
77import { notify , NOTIFY_TYPE } from '../components/Notification/actions'
8+ import * as searchAPI from 'backendAPI/searchAPI'
89
910const log = console . log || ( x => x )
1011const warn = console . warn || ( x => x )
@@ -93,6 +94,9 @@ class FsSocketClient {
9394 if ( TtySocketClient . $$singleton ) {
9495 TtySocketClient . $$singleton . close ( ) ;
9596 }
97+ if ( SearchSocketClient . $$singleton ) {
98+ SearchSocketClient . $$singleton . close ( ) ;
99+ }
96100 }
97101}
98102
@@ -179,4 +183,104 @@ class TtySocketClient {
179183 }
180184}
181185
182- export { FsSocketClient , TtySocketClient }
186+ class SearchSocketClient {
187+ constructor ( ) {
188+ if ( SearchSocketClient . $$singleton ) return SearchSocketClient . $$singleton
189+
190+ const wsUrl = config . wsURL
191+ const firstSlashIdx = wsUrl . indexOf ( '/' , 8 )
192+ const [ host , path ] = firstSlashIdx === - 1 ? [ wsUrl , '' ] : [ wsUrl . substring ( 0 , firstSlashIdx ) , wsUrl . substring ( firstSlashIdx ) ]
193+
194+ const url = `${ host } :8066/search/sockjs`
195+
196+ this . sockJSConfigs = [ url , { } , { server : `${ config . spaceKey } ` , transports : 'websocket' } ]
197+
198+ this . backoff = getBackoff ( {
199+ delayMin : 1500 ,
200+ delayMax : 10000 ,
201+ } )
202+ this . maxAttempts = 5
203+
204+ SearchSocketClient . $$singleton = this
205+ emitter . on ( E . SOCKET_RETRY , ( ) => {
206+ this . reconnect ( )
207+ } )
208+ }
209+
210+ connect ( ) {
211+ if ( ! this . socket || ! this . stompClient ) {
212+ this . socket = new SockJS ( ...this . sockJSConfigs )
213+ this . stompClient = Stomp . over ( this . socket )
214+ this . stompClient . debug = false // stop logging PING/PONG
215+ }
216+ const success = ( ) => {
217+ runInAction ( ( ) => config . searchSocketConnected = true )
218+ this . backoff . reset ( )
219+ this . successCallback ( this . stompClient )
220+ }
221+ const error = ( frame ) => {
222+ if ( this . shouldClose ) {
223+ this . shouldClose = false ;
224+ return ;
225+ }
226+ log ( '[SEARCH Socket] SearchSocket error' , this . socket )
227+ switch ( this . socket . readyState ) {
228+ case SockJS . CLOSING :
229+ case SockJS . CLOSED :
230+ runInAction ( ( ) => config . searchSocketConnected = false )
231+ this . reconnect ( )
232+ break
233+ case SockJS . OPEN :
234+ log ( 'FRAME ERROR' , frame )
235+ break
236+ default :
237+ }
238+ this . errorCallback ( frame )
239+ }
240+
241+ this . stompClient . connect ( { } , success , error )
242+ }
243+
244+ reconnect ( ) {
245+ if ( config . searchSocketConnected ) return
246+ log ( `[SEARCH Socket] reconnect searchSocket ${ this . backoff . attempts } ` )
247+ // unset this.socket
248+ this . socket = undefined
249+ if ( this . backoff . attempts <= this . maxAttempts ) {
250+ const retryDelay = this . backoff . duration ( )
251+ log ( `Retry after ${ retryDelay } ms` )
252+ const timer = setTimeout (
253+ this . connect . bind ( this )
254+ , retryDelay )
255+ } else {
256+ // must emit ,ops correct?
257+ // emitter.emit(E.SOCKET_TRIED_FAILED)
258+ notify ( { message : i18n `global.onSocketError` , notifyType : NOTIFY_TYPE . ERROR } )
259+ this . backoff . reset ( )
260+ warn ( 'Sock connected failed, something may be broken, reload page and try again' )
261+ }
262+ }
263+
264+ close ( ) {
265+ const self = this
266+ if ( config . searchSocketConnected ) {
267+ searchAPI . searchWorkspaceDown ( ) ;
268+ self . shouldClose = true ;
269+ self . socket . close ( ) ;
270+ // must emit ???
271+ // emitter.emit(E.SOCKET_TRIED_FAILED);
272+ runInAction ( ( ) => config . searchSocketConnected = false ) ;
273+ }
274+ }
275+
276+ subscribe = ( topic , process ) => {
277+ this . stompClient . subscribe ( topic , process ) ;
278+ }
279+
280+ send = ( mapping , headers , data ) => {
281+ this . stompClient . send ( mapping , headers , data ) ;
282+ }
283+ }
284+
285+
286+ export { FsSocketClient , TtySocketClient , SearchSocketClient }
0 commit comments