import { OPEN } from "ws" ; import { Controller , Get , Query , WebSocketServer , Ws } from "../core" ; import WebsocketEmitter , { WebsocketEvent , WsClient , } from "../core/WebsocketEmitter" ; import BaseController from "./BaseController" ; interface JoinPage { room : string ; screenName : string ; projectName : string ; pageId : string ; page : string ; master ? : boolean ; } interface StateSyncMsg { key : string ; sender : string ; state : { [ key ] : any ; } ; } interface SyncPageMsg { page : string ; data : { [ key ] : any ; } ; } @ Controller ( "/ws" ) export default class ScreenSyncController extends BaseController { @ WebSocketServer ( ) private wss ! : WebsocketEmitter ; param params @ Get ( "/connects" ) async getPageByRoom ( @ Query ( "room" ) room ) { const clients = this . getRoomClients ( room ) ; const pages = [ ] ; clients . forEach ( ( v ) => { const clientData = v . data ; if ( ! pages . find ( ( p ) => p . page === clientData . page ) ) { pages . push ( { ... clientData } ) ; } } ) ; return this . success ( pages ) ; } param event @ Ws ( WebsocketEvent . disconnect ) disconnect ( target ) { const { room } = target ; this . sendAll ( room , { event : "join" , data : this . wss . getClientsByRoom ( room ) . map ( ( client ) => client . data ) , } ) ; } /**
     * 页面加入房间
     */ @ Ws ( "/join" ) join ( data , target ) { const { room } = data ; if ( room ) { target . room = room ; } target . data = data ; } /**
     * 组件状态同步
     */ @ Ws ( "/sync" ) sync ( data , target ) { const { room , data : pageInfo } = target ; this . sendAll ( room , { event : "sync" , data , } , pageInfo . page , target . id ) ; } param { * } event @ Ws ( "/syncPage" ) syncPage ( data , target ) { const { room } = target ; this . sendAll ( room , { event : "syncPage" , data , } , data . page ) ; } param room param page getRoomClients ( room , page ? ) { const clients = this . wss . getClientsByRoom ( room ) || [ ] ; return page ? clients . filter ( ( val ) => val . data && val . data . page === page ) : clients ; } param { object } msg param { string } room param { object } page param { string } filterId sendAll ( room , msg , page ? , filterId ? ) { const clients = this . getRoomClients ( room , page ) ; clients . forEach ( ( client ) => { if ( client . id !== filterId ) this . sendMessage ( client , msg ) ; } ) ; } param { object } client param { object } msg sendMessage ( client , msg ) { try { if ( client && client . socket && client . socket . readyState === OPEN ) { const msgString = JSON . stringify ( msg ) ; client . socket . send ( msgString , ( err ) => { if ( err ) { console . error ( err ) ; } } ) ; } } catch ( e ) { console . error ( e ) ; } } }