index.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. const express = require('express');
  2. const http = require( 'http');
  3. const WebSocket = require('ws');
  4. const app = express();
  5. //initialize a simple http server
  6. const server = http.createServer(app);
  7. //initialize the WebSocket server instance
  8. const wss = new WebSocket.Server({ server });
  9. const messages = [];
  10. const sockets = [];
  11. let userCount = 0;
  12. function noPromise(){
  13. let resolve, reject;
  14. let np = new Promise((ok, fail) => {resolve = ok; reject = fail});
  15. np.resolve = resolve;
  16. np.reject = reject;
  17. return np
  18. }
  19. function asynchronize({s, chunkEventName, endEventName}){
  20. return function* wrapper(){
  21. const chunks = {};
  22. const promises = {};
  23. const clear = i => (delete chunks[i], delete promises[i])
  24. let chunkCount = 0;
  25. let promiseCount = 0;
  26. let end = false;
  27. s.on(chunkEventName, data => {
  28. chunks[chunkCount] = data
  29. if (chunkCount in promises){
  30. promises[chunkCount].resolve(chunks[chunkCount])
  31. clear(chunkCount)
  32. }
  33. chunkCount++
  34. })
  35. s.on(endEventName, () => {
  36. end = true;
  37. for (let i in promises){
  38. promises[i].reject(new Error('End Of S'))
  39. }
  40. })
  41. while (!end){
  42. let p = noPromise()
  43. if (promiseCount in chunks){
  44. p.resolve(chunks[promiseCount])
  45. clear(promiseCount)
  46. }
  47. promises[promiseCount] = p;
  48. promiseCount++
  49. yield p;
  50. }
  51. }
  52. }
  53. function broadcast(wtf){
  54. for (s of sockets){
  55. console.log(wtf)
  56. s.send(JSON.stringify(wtf))
  57. }
  58. }
  59. let RPC = {
  60. addMessage({nick, message}){
  61. messages.push({nick, message, timestamp: (new Date).getTime()})
  62. broadcast({func: 'addMessage', nick, message})
  63. return messages.length;
  64. },
  65. getMessages({offset=0}){
  66. return messages.slice(offset)
  67. },
  68. getUserCount(){
  69. return userCount;
  70. }
  71. }
  72. wss.on('connection', async ws => {
  73. let gena = asynchronize({s:ws, chunkEventName: 'message', endEventName: 'close'})
  74. sockets.push(ws)
  75. userCount++;
  76. for (let p of gena()){
  77. try {
  78. let message = await p;
  79. let data = JSON.parse(message)
  80. if (data.func in RPC){
  81. ws.send(JSON.stringify(RPC[data.func](data)))
  82. }
  83. }
  84. catch(e){
  85. if (e.message === 'End Of S'){
  86. console.log('client OTPAL')
  87. break;
  88. }
  89. console.log(e)
  90. }
  91. }
  92. sockets = sockets.filter(s => s !== ws)
  93. userCount--;
  94. });
  95. app.use(express.static('public'));
  96. //start our server
  97. server.listen(process.env.PORT || 8999, () => {
  98. console.log(`Server started on port ${server.address().port} :)`);
  99. });