import { Logger } from "amazon-chime-sdk-js" ; import { WebSocketClient , WebSocketMessage } from "../WebSocketClient" ; import AsyncLock from "async-lock" ; export const DrawingCmd = { DRAW : "DRAW" , ERASE : "ERASE" , CLEAR : "CLEAR" , SYNC_SCREEN : "SYNC_SCREEN" , } as const ; type DrawingCmd = typeof DrawingCmd [ keyof typeof DrawingCmd ] ; export const DrawingMode = { DRAW : "DRAW" , ERASE : "ERASE" , DISABLE : "DISABLE" , } as const ; type DrawingMode = typeof DrawingMode [ keyof typeof DrawingMode ] ; type WhiteboardClientListener = ( data : DrawingData [ ] ) => void ; export type DrawingData = { drawingCmd : DrawingCmd ; startXR : number ; startYR : number ; endXR : number ; endYR : number ; stroke : string ; lineWidth : number ; canvasId ? : string ; } ; const TOPIC_NAME = "WHITEBOARD" ; const SEND_INTERVAL_TIME = 1000 ; const SEND_INTERVAL_NUM = 100 ; export class WebSocketWhiteboardClient { lineWidth = 3 ; drawingStroke = "#aaaaaaaa" ; drawingMode : DrawingMode = DrawingMode . DISABLE ; drawingData : DrawingData [ ] = [ ] ; private _whiteboardDataUpdateListeners : WhiteboardClientListener [ ] = [ ] ; lock = new AsyncLock ( ) ; private drawingDataBuffer : DrawingData [ ] = [ ] ; private wsClient : WebSocketClient ; constructor ( attendeeId , messagingURLWithQuery ) { console . log ( `[FlectChimeClient][WebSocketWhiteboardClient] creating.. ${ attendeeId }, ${ messagingURLWithQuery }` ) ; this . wsClient = new WebSocketClient ( attendeeId , messagingURLWithQuery ) ; this . wsClient . connect ( ) ; this . startMonitor ( ) ; this . wsClient . addEventListener ( TOPIC_NAME , ( wsMessages ) => { this . drawingData = wsMessages . reduce ( ( sum , cur ) => { return [ ... sum , ... ( cur . data as DrawingData [ ] ) ] ; } , [ ] ) ; this . _whiteboardDataUpdateListeners . forEach ( ( listener ) => { listener ( this . drawingData ) ; } ) ; } ) ; } addWhiteboardDataUpdateListener = ( l ) => { this . _whiteboardDataUpdateListeners . push ( l ) ; } ; removeWhiteboardDataUpdateListener = ( l ) => { this . _whiteboardDataUpdateListeners = this . _whiteboardDataUpdateListeners . filter ( ( x ) => { return x !== l ; } ) ; } ; addDrawingData = ( data ) => { this . wsClient . loopbackMessage ( TOPIC_NAME , [ data ] ) ; this . lock . acquire ( "whiteboard" , async ( ) => { this . drawingDataBuffer . push ( data ) ; if ( this . drawingDataBuffer . length > SEND_INTERVAL_NUM ) { this . sendDrawingBuffer ( ) ; } return "Successful" ; } , ( error , result ) => { if ( error ) { console . log ( `[FlectChimeClient][WebSocketWhiteboardClient] addDrawingData error` ) ; } else { } } ) ; } ; startMonitor = ( ) => { this . lock . acquire ( "whiteboard" , async ( ) => { if ( this . drawingDataBuffer . length > 0 ) { this . sendDrawingBuffer ( ) ; } setTimeout ( this . startMonitor , SEND_INTERVAL_TIME ) ; return "Successful" ; } , ( error , result ) => { if ( error ) { console . log ( `[FlectChimeClient][WebSocketWhiteboardClient] startMonitor error` ) ; } else { } } ) ; } ; private sendDrawingBuffer = ( ) => { this . wsClient . sendMessage ( TOPIC_NAME , this . drawingDataBuffer ) ; this . drawingDataBuffer = [ ] ; } ; }