@@ -4,7 +4,8 @@ import { SocketMessage } from "./SocketMessage";
44import { Message , JSONfn } from "./Messages/Message" ;
55import { Config } from "./Config" ;
66import { amqpwrapper , QueueMessageOptions , amqpqueue } from "./amqpwrapper" ;
7- import { NoderedUtil , Base , InsertOneMessage , QueueMessage , MapReduceMessage , QueryMessage , UpdateOneMessage , UpdateManyMessage , DeleteOneMessage , User , mapFunc , reduceFunc , finalizeFunc , QueuedMessage , QueuedMessageCallback } from "openflow-api" ;
7+ import { NoderedUtil , Base , InsertOneMessage , QueueMessage , MapReduceMessage , QueryMessage , UpdateOneMessage , UpdateManyMessage , DeleteOneMessage , User , mapFunc , reduceFunc , finalizeFunc , QueuedMessage , QueuedMessageCallback , WatchEventMessage } from "openflow-api" ;
8+ import { ChangeStream } from "mongodb" ;
89// import { Mutex } from "./Mutex";
910
1011interface IHashTable < T > {
@@ -39,6 +40,11 @@ const Semaphore = (n) => ({
3940} ) ;
4041const semaphore = Semaphore ( 1 ) ;
4142
43+ export class clsstream {
44+ public stream : ChangeStream ;
45+ public id : string ;
46+ public callback : any ;
47+ }
4248
4349export class WebSocketServerClient {
4450 public jwt : string ;
@@ -91,13 +97,14 @@ export class WebSocketServerClient {
9197 socketObject . on ( "close" , ( e : CloseEvent ) : void => this . close ( e ) ) ;
9298 }
9399 private open ( e : Event ) : void {
94- this . _logger . info ( "WebSocket connection opened " + e ) ;
100+ this . _logger . info ( "WebSocket connection opened " + e + " " + this . id ) ;
95101 }
96102 private close ( e : CloseEvent ) : void {
97- this . _logger . info ( "WebSocket connection closed " + e ) ;
103+ this . _logger . info ( "WebSocket connection closed " + e + " " + this . id + "/" + this . clientagent ) ;
104+ this . Close ( ) ;
98105 }
99106 private error ( e : Event ) : void {
100- this . _logger . error ( "WebSocket error encountered " + e ) ;
107+ this . _logger . error ( "WebSocket error encountered " + e + " " + this . id + "/" + this . clientagent ) ;
101108 }
102109 public queuecount ( ) : number {
103110 if ( this . _queues == null ) return 0 ;
@@ -121,6 +128,9 @@ export class WebSocketServerClient {
121128 if ( this . queuecount ( ) > 0 ) {
122129 this . CloseConsumers ( ) ;
123130 }
131+ if ( this . streamcount ( ) > 0 ) {
132+ this . CloseConsumers ( ) ;
133+ }
124134 return ;
125135 }
126136 if ( this . _socketObject . readyState === this . _socketObject . CLOSED || this . _socketObject . readyState === this . _socketObject . CLOSING ) {
@@ -172,6 +182,7 @@ export class WebSocketServerClient {
172182 }
173183 public async Close ( ) : Promise < void > {
174184 await this . CloseConsumers ( ) ;
185+ await this . CloseStreams ( ) ;
175186 if ( this . _socketObject != null ) {
176187 try {
177188 this . _socketObject . removeListener ( "open" , ( e : Event ) : void => this . open ( e ) ) ;
@@ -423,6 +434,70 @@ export class WebSocketServerClient {
423434 var msg : Message = new Message ( ) ; msg . command = "deleteone" ; msg . data = JSON . stringify ( q ) ;
424435 q = await this . Send < DeleteOneMessage > ( msg ) ;
425436 }
437+ streams : clsstream [ ] = [ ] ;
438+ public streamcount ( ) : number {
439+ if ( this . streams == null ) return 0 ;
440+ return this . streams . length ;
441+ }
442+ async CloseStreams ( ) : Promise < void > {
443+ if ( this . streams != null && this . streams . length > 0 ) {
444+ for ( var i = this . streams . length - 1 ; i >= 0 ; i -- ) {
445+ try {
446+ if ( this . streams [ i ] != null && this . streams [ i ] . stream != null && ! this . streams [ i ] . stream . isClosed ( ) ) {
447+ await this . streams [ i ] . stream . close ( ) ;
448+ }
449+ this . streams . splice ( i , 1 ) ;
450+ } catch ( error ) {
451+ this . _logger . error ( "WebSocketclient::CloseStreams " + error + " " + this . id + "/" + this . clientagent ) ;
452+ }
453+ }
454+ }
455+ }
456+ async CloseStream ( id : string ) : Promise < void > {
457+ if ( this . streams != null && this . streams . length > 0 ) {
458+ for ( var i = this . streams . length - 1 ; i >= 0 ; i -- ) {
459+ try {
460+ if ( this . streams [ i ] != null && this . streams [ i ] . id == id ) {
461+ if ( ! this . streams [ i ] . stream . isClosed ( ) ) await this . streams [ i ] . stream . close ( ) ;
462+ this . streams . splice ( i , 1 ) ;
463+ }
464+ } catch ( error ) {
465+ this . _logger . error ( "WebSocketclient::CloseStream " + error + " " + this . id + "/" + this . clientagent ) ;
466+ }
467+ }
468+ }
469+ }
470+ async UnWatch ( id : string , jwt : string ) : Promise < void > {
471+ this . CloseStream ( id ) ;
472+ }
473+ async Watch ( aggregates : object [ ] , collectionname : string , jwt : string ) : Promise < string > {
474+ var stream : clsstream = new clsstream ( ) ;
475+ stream . id = Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) ;
476+ stream . stream = await Config . db . watch ( aggregates , collectionname , jwt ) ;
477+ this . streams . push ( stream ) ;
426478
479+ const options = { fullDocument : "updateLookup" } ;
480+ const me = this ;
481+ try {
482+ ( stream . stream as any ) . on ( "change" , next => {
483+ try {
484+ // me._logger.info(JSON.stringify(next, null, 4));
485+ me . _logger . info ( "Watch: " + JSON . stringify ( next . documentKey ) ) ;
486+ const msg : SocketMessage = SocketMessage . fromcommand ( "watchevent" ) ;
487+ var q = new WatchEventMessage ( ) ;
488+ q . id = stream . id ;
489+ q . result = next ;
490+ msg . data = JSON . stringify ( q ) ;
491+ me . _socketObject . send ( msg . tojson ( ) ) ;
492+ } catch ( error ) {
493+ this . _logger . error ( "WebSocketclient::Watch::changeListener " + error + " " + this . id + "/" + this . clientagent ) ;
494+ }
495+ } , options ) ;
496+ return stream . id ;
497+ } catch ( error ) {
498+ this . _logger . error ( "WebSocketclient::Watch " + error + " " + this . id + "/" + this . clientagent ) ;
499+ throw error ;
500+ }
501+ }
427502
428503}
0 commit comments