WSServer.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import ws from "ws";
  2. import { EventEmitter } from "events";
  3. interface EndEvent {
  4. action: "ended"
  5. }
  6. interface WaitingForVideoEvent {
  7. action: "waitingForVideo"
  8. }
  9. type ClientMessage = EndEvent | WaitingForVideoEvent
  10. interface WebSocketServer {
  11. on(event: "ended", listener: ()=>void): this;
  12. on(event: "waitingForVideo", listener: ()=>void): this;
  13. emit(event: "ended"): boolean;
  14. emit(event: "waitingForVideo"): boolean;
  15. }
  16. class WebSocketServer extends EventEmitter {
  17. server?: ws.Server;
  18. private interval?: NodeJS.Timeout;
  19. private inputs: {
  20. StartStopButton?: HTMLButtonElement,
  21. ClientsAmountField?: HTMLSpanElement
  22. } = {};
  23. constructor(private port: number = 8045){
  24. super();
  25. if(! (!isNaN(port) && port > 0 && port < 65535)){
  26. throw new Error("Malicious port")
  27. }
  28. }
  29. status(): boolean{
  30. return !!this.server;
  31. }
  32. changePort(newport: number){
  33. if(this.status()){
  34. throw new Error("Can't change port while server is running");
  35. }
  36. this.port = newport;
  37. }
  38. start(){
  39. if(this.status()){
  40. console.log("Trying to start websocket when it is already running");
  41. return
  42. }
  43. this.changePort(window.settings.options.wsport);
  44. this.server = new ws.Server({
  45. port: this.port,
  46. clientTracking: true
  47. });
  48. this.server.on("close", ()=>{
  49. this.server = undefined;
  50. })
  51. this.server.on("connection", (cl) => {
  52. cl.on("message", msg => {
  53. this.connectionHandler(msg.toString());
  54. })
  55. })
  56. }
  57. stop(){
  58. if(!this.status()){
  59. console.log("Trying to stop websocket when it's not running");
  60. return
  61. }
  62. this.server.close();
  63. }
  64. connectionHandler(rawMsg: string){
  65. let msg: ClientMessage;
  66. try {
  67. msg= JSON.parse(rawMsg);
  68. } catch (error) {
  69. console.log("Error while parsing incoming message");
  70. console.log(error);
  71. console.log(rawMsg);
  72. return;
  73. }
  74. switch (msg.action) {
  75. case "ended":
  76. this.emit("ended");
  77. break;
  78. case "waitingForVideo":
  79. this.emit("waitingForVideo");
  80. break;
  81. default:
  82. break;
  83. }
  84. }
  85. clientsAmount(): number{
  86. if(this.server){
  87. return this.server.clients.size;
  88. }
  89. return 0;
  90. }
  91. bind(
  92. StaStoBtn: HTMLButtonElement,
  93. ClientsAmountField: HTMLSpanElement
  94. ){
  95. this.inputs.StartStopButton = StaStoBtn;
  96. this.inputs.ClientsAmountField = ClientsAmountField;
  97. let refresher = () => this.updateElement();
  98. this.interval = setInterval(refresher, 333);
  99. setTimeout(refresher, 0);
  100. this.inputs.StartStopButton.addEventListener("click", e => {
  101. console.log("Start stop");
  102. if(this.status()){
  103. this.stop();
  104. }else{
  105. this.changePort(window.settings.options.wsport)
  106. this.start();
  107. }
  108. })
  109. }
  110. updateElement(){
  111. let status = document.getElementById("wssStatus");
  112. if(this.status()){
  113. status.innerText = "Online"
  114. status.style.color = "Green";
  115. if(this.inputs.StartStopButton)
  116. this.inputs.StartStopButton.innerText = "Stop";
  117. }else{
  118. status.innerText = "Offline"
  119. status.style.color = "red";
  120. if(this.inputs.StartStopButton)
  121. this.inputs.StartStopButton.innerText = "Start";
  122. }
  123. this.inputs.ClientsAmountField.textContent =
  124. this.clientsAmount().toString();
  125. }
  126. sendToAll(msg: string){
  127. if(this.server){
  128. this.server.clients.forEach((value) => {
  129. value.send(msg)
  130. })
  131. }
  132. }
  133. }
  134. export default WebSocketServer;