1- import { error_alert , randomid } from "./utils" ;
1+ import { error_alert , randomid , ReliableSender } from "./utils" ;
22import { state } from "./state" ;
33import { t } from "./i18n" ;
44
@@ -181,6 +181,7 @@ export class HttpSession implements Session {
181181 webio_session_id : string = '' ;
182182 debug = false ;
183183
184+ private sender : ReliableSender = null ;
184185 private _executed_command_msg_id = - 1 ;
185186 private _closed = false ;
186187 private _session_create_callbacks : ( ( ) => void ) [ ] = [ ] ;
@@ -193,6 +194,7 @@ export class HttpSession implements Session {
193194 let url = new URL ( api_url , window . location . href ) ;
194195 url . search = "?app=" + app_name ;
195196 this . api_url = url . href ;
197+ this . sender = new ReliableSender ( this . _send . bind ( this ) ) ;
196198 }
197199
198200 on_session_create ( callback : ( ) => void ) : void {
@@ -224,21 +226,21 @@ export class HttpSession implements Session {
224226 contentType : "application/json; charset=utf-8" ,
225227 dataType : "json" ,
226228 headers : { "webio-session-id" : this . webio_session_id } ,
227- success : function ( data : { commands : Command [ ] [ ] , seq : number , event : number } ,
229+ success : function ( data : { commands : Command [ ] [ ] , seq : number , event : number , ack : number } ,
228230 textStatus : string , jqXHR : JQuery . jqXHR ) {
229231 safe_poprun_callbacks ( that . _session_create_callbacks , 'session_create_callback' ) ;
230232 that . _on_request_success ( data , textStatus , jqXHR ) ;
231- if ( that . webio_session_id . startsWith ( "NEW-" ) ) {
233+ if ( that . webio_session_id . startsWith ( "NEW-" ) ) {
232234 that . webio_session_id = that . webio_session_id . substring ( 4 ) ;
233235 }
234- } ,
235- error : function ( ) {
236- console . error ( 'Http pulling failed' ) ;
237236 }
238237 } )
239238 }
240239
241- private _on_request_success ( data : { commands : Command [ ] [ ] , seq : number } , textStatus : string , jqXHR : JQuery . jqXHR ) {
240+ private _on_request_success ( data : { commands : Command [ ] [ ] , seq : number , ack : number } ,
241+ textStatus : string , jqXHR : JQuery . jqXHR ) {
242+ this . sender . ack ( data . ack ) ;
243+
242244 let msg_start_idx = this . _executed_command_msg_id - data . seq + 1 ;
243245 if ( data . commands . length <= msg_start_idx )
244246 return ;
@@ -258,54 +260,78 @@ export class HttpSession implements Session {
258260
259261 send_message ( msg : ClientEvent , onprogress ?: ( loaded : number , total : number ) => void ) : void {
260262 if ( this . debug ) console . info ( '<<<' , msg ) ;
261- this . _send ( {
262- data : JSON . stringify ( msg ) ,
263- contentType : "application/json; charset=utf-8" ,
264- } , onprogress ) ;
263+ this . sender . add_send_task ( {
264+ data : msg ,
265+ json : true ,
266+ onprogress : onprogress ,
267+ } )
265268 }
266269
267270 send_buffer ( data : Blob , onprogress ?: ( loaded : number , total : number ) => void ) : void {
268271 if ( this . debug ) console . info ( '<<< Blob data...' ) ;
269- this . _send ( {
272+ this . sender . add_send_task ( {
270273 data : data ,
271- cache : false ,
272- processData : false ,
273- contentType : 'application/octet-stream' ,
274- } , onprogress ) ;
274+ json : false ,
275+ onprogress : onprogress ,
276+ } , false )
275277 }
276278
277- _send ( options : { [ key : string ] : any ; } , onprogress ?: ( loaded : number , total : number ) => void ) : void {
278- if ( this . closed ( ) )
279- return error_alert ( t ( "disconnected_with_server" ) ) ;
280-
281- $ . ajax ( {
282- ...options ,
283- type : "POST" ,
284- url : `${ this . api_url } &ack=${ this . _executed_command_msg_id } ` ,
285- dataType : "json" ,
286- headers : { "webio-session-id" : this . webio_session_id } ,
287- success : this . _on_request_success . bind ( this ) ,
288- xhr : function ( ) {
289- let xhr = new window . XMLHttpRequest ( ) ;
290- // Upload progress
291- xhr . upload . addEventListener ( "progress" , function ( evt ) {
292- if ( evt . lengthComputable && onprogress ) {
293- onprogress ( evt . loaded , evt . total ) ;
294- }
295- } , false ) ;
296- return xhr ;
297- } ,
298- error : function ( ) {
299- console . error ( 'Http push blob data failed' ) ;
300- error_alert ( t ( "connect_fail" ) ) ;
279+ _send ( params : { [ key : string ] : any ; } [ ] , seq : number ) : Promise < void > {
280+ if ( this . closed ( ) ) {
281+ this . sender . stop ( ) ;
282+ error_alert ( t ( "disconnected_with_server" ) ) ;
283+ return Promise . reject ( ) ;
284+ }
285+ let data : any , ajax_options : any ;
286+ let json = params . some ( p => p . json ) ;
287+ if ( json ) {
288+ data = JSON . stringify ( params . map ( p => p . data ) ) ;
289+ ajax_options = {
290+ contentType : "application/json; charset=utf-8" ,
301291 }
292+ } else {
293+ data = params [ 0 ] . data ;
294+ ajax_options = {
295+ cache : false ,
296+ processData : false ,
297+ contentType : 'application/octet-stream' ,
298+ }
299+ }
300+ return new Promise ( ( resolve , reject ) => {
301+ $ . ajax ( {
302+ data : data ,
303+ ...ajax_options ,
304+ type : "POST" ,
305+ url : `${ this . api_url } &ack=${ this . _executed_command_msg_id } &seq=${ seq } ` ,
306+ dataType : "json" ,
307+ headers : { "webio-session-id" : this . webio_session_id } ,
308+ success : this . _on_request_success . bind ( this ) ,
309+ xhr : function ( ) {
310+ let xhr = new window . XMLHttpRequest ( ) ;
311+ // Upload progress
312+ xhr . upload . addEventListener ( "progress" , function ( evt ) {
313+ if ( evt . lengthComputable ) {
314+ params . forEach ( p => {
315+ if ( p . onprogress ) // only the first one
316+ p . onprogress ( evt . loaded , evt . total ) ;
317+ p . onprogress = null ;
318+ } ) ;
319+ }
320+ } , false ) ;
321+ return xhr ;
322+ } ,
323+ error : function ( ) {
324+ console . error ( 'Http push event failed, will retry' ) ;
325+ }
326+ } ) . always ( ( ) => resolve ( ) ) ;
302327 } ) ;
303328 }
304329
305330 close_session ( ) : void {
306331 this . _closed = true ;
307332 safe_poprun_callbacks ( this . _session_close_callbacks , 'session_close_callback' ) ;
308333 clearInterval ( this . interval_pull_id ) ;
334+ this . sender . stop ( ) ;
309335 }
310336
311337 closed ( ) : boolean {
0 commit comments