@@ -682,6 +682,19 @@ class ApiClient {
682
682
return val . substring ( val . indexOf ( '=' ) + 1 ) . replace ( "'" , '%27' ) ;
683
683
}
684
684
685
+ /**
686
+ * Gets the server time as a UTC formatted string.
687
+ * @returns {Promise } Promise that it's fulfilled on request completion.
688
+ */
689
+ getServerTime ( ) {
690
+ const url = this . getUrl ( 'GetUTCTime' ) ;
691
+
692
+ return this . ajax ( {
693
+ type : 'GET' ,
694
+ url : url
695
+ } ) ;
696
+ }
697
+
685
698
getDownloadSpeed ( byteSize ) {
686
699
const url = this . getUrl ( 'Playback/BitrateTest' , {
687
700
Size : byteSize
@@ -3242,6 +3255,30 @@ class ApiClient {
3242
3255
} ) ;
3243
3256
}
3244
3257
3258
+ /**
3259
+ * Sends a SyncPlay command.
3260
+ * @param {String } sessionId The session that is making the request.
3261
+ * @param {String } command The command to request.
3262
+ * @param {Object } options Options to send along with the command.
3263
+ * @returns {Promise } Promise that it's fulfilled on request completion.
3264
+ */
3265
+ sendSyncPlayCommand ( sessionId , command , options ) {
3266
+ if ( ! sessionId ) {
3267
+ throw new Error ( "null sessionId" ) ;
3268
+ }
3269
+
3270
+ if ( ! command ) {
3271
+ throw new Error ( "null command" ) ;
3272
+ }
3273
+
3274
+ const url = this . getUrl ( `SyncPlay/${ sessionId } /${ command } ` , options || { } ) ;
3275
+
3276
+ return this . ajax ( {
3277
+ type : 'POST' ,
3278
+ url : url
3279
+ } ) ;
3280
+ }
3281
+
3245
3282
createPackageReview ( review ) {
3246
3283
const url = this . getUrl ( `Packages/Reviews/${ review . id } ` , review ) ;
3247
3284
@@ -3455,11 +3492,43 @@ function onMessageReceivedInternal(instance, msg) {
3455
3492
if ( user . Id === instance . getCurrentUserId ( ) ) {
3456
3493
instance . _currentUser = null ;
3457
3494
}
3495
+ } else if ( msg . MessageType === 'KeepAlive' ) {
3496
+ console . debug ( 'Received KeepAlive from server.' ) ;
3497
+ } else if ( msg . MessageType === 'ForceKeepAlive' ) {
3498
+ console . debug ( `Received ForceKeepAlive from server. Timeout is ${ msg . Data } seconds.` ) ;
3499
+ instance . sendWebSocketMessage ( 'KeepAlive' ) ;
3500
+ scheduleKeepAlive ( instance , msg . Data ) ;
3458
3501
}
3459
3502
3460
3503
events . trigger ( instance , 'message' , [ msg ] ) ;
3461
3504
}
3462
3505
3506
+ /**
3507
+ * Starts a poller that sends KeepAlive messages using a WebSocket connection.
3508
+ * @param {Object } instance The WebSocket connection.
3509
+ * @param {number } timeout The number of seconds after which the WebSocket is considered lost by the server.
3510
+ * @returns {number } The id of the interval.
3511
+ */
3512
+ function scheduleKeepAlive ( instance , timeout ) {
3513
+ clearKeepAlive ( instance ) ;
3514
+ instance . keepAliveInterval = setInterval ( ( ) => {
3515
+ instance . sendWebSocketMessage ( 'KeepAlive' ) ;
3516
+ } , timeout * 1000 * 0.5 ) ;
3517
+ return instance . keepAliveInterval ;
3518
+ }
3519
+
3520
+ /**
3521
+ * Stops the poller that is sending KeepAlive messages on a WebSocket connection.
3522
+ * @param {Object } instance The WebSocket connection.
3523
+ */
3524
+ function clearKeepAlive ( instance ) {
3525
+ console . debug ( 'Clearing KeepAlive for' , instance ) ;
3526
+ if ( instance . keepAliveInterval ) {
3527
+ clearInterval ( instance . keepAliveInterval ) ;
3528
+ instance . keepAliveInterval = null ;
3529
+ }
3530
+ }
3531
+
3463
3532
function onWebSocketOpen ( ) {
3464
3533
const instance = this ;
3465
3534
console . log ( 'web socket connection opened' ) ;
@@ -3468,13 +3537,15 @@ function onWebSocketOpen() {
3468
3537
3469
3538
function onWebSocketError ( ) {
3470
3539
const instance = this ;
3540
+ clearKeepAlive ( instance ) ;
3471
3541
events . trigger ( instance , 'websocketerror' ) ;
3472
3542
}
3473
3543
3474
3544
function setSocketOnClose ( apiClient , socket ) {
3475
3545
socket . onclose = ( ) => {
3476
3546
console . log ( 'web socket closed' ) ;
3477
3547
3548
+ clearKeepAlive ( socket ) ;
3478
3549
if ( apiClient . _webSocket === socket ) {
3479
3550
console . log ( 'nulling out web socket' ) ;
3480
3551
apiClient . _webSocket = null ;
0 commit comments