index.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. let socket;
  2. function openPromise(){
  3. let resolve, reject;
  4. let np = new Promise((ok, fail) => {resolve = ok; reject = fail});
  5. np.resolve = resolve;
  6. np.reject = reject;
  7. return np
  8. }
  9. function asynchronize({s, chunkEventName, endEventName}){
  10. return async function* (){
  11. const chunks = {};
  12. const promises = {};
  13. const clear = i => (delete chunks[i], delete promises[i])
  14. let chunkCount = 0;
  15. let promiseCount = 0;
  16. let end = false;
  17. if (!('on' in s)){ //no on method in browser
  18. s.on = function(eventName, callback){ //polyfill
  19. this['on' + eventName] = callback;
  20. }
  21. }
  22. //check availability of chunk and promise. If any, resolve promise, and clear both from queue
  23. const chunkAndPromise = i => (i in chunks) &&
  24. (i in promises) && (
  25. promises[i].resolve(chunks[i]),
  26. clear(i))
  27. s.on(chunkEventName, data => {
  28. chunks[chunkCount] = data
  29. chunkAndPromise(chunkCount)
  30. chunkCount++
  31. })
  32. s.on(endEventName, () => {
  33. end = true;
  34. for (let i in promises){
  35. promises[i].reject(new Error('End Of S'))
  36. }
  37. })
  38. while (!end){
  39. let p;
  40. promises[promiseCount] = p = openPromise();
  41. chunkAndPromise(promiseCount)
  42. promiseCount++;
  43. yield p; //yield promise outside
  44. }
  45. }
  46. }
  47. function msg2dom({nick, message, timestamp}){
  48. const div = document.createElement('div')
  49. div.innerHTML = `<b>${nick}</b>:${message}`
  50. return div;
  51. }
  52. function userCount2dom({value}){
  53. const div = document.createElement('div')
  54. div.innerHTML = `<b>${nick}</b>:${message}`
  55. return div;
  56. }
  57. let RPC = {
  58. addMessage(data){
  59. chat.appendChild(msg2dom(data))
  60. },
  61. getUserCount({value}){
  62. chat.appendChild(userCount2dom({value}))
  63. }
  64. };
  65. (async () => {
  66. while (true){
  67. try{
  68. socket = new WebSocket(`ws://${location.host}/`);
  69. let aGena = asynchronize({s: socket, chunkEventName: 'message', endEventName: 'close'});
  70. for await (let msg of aGena()){
  71. let data = JSON.parse(msg.data)
  72. if (data.func in RPC){
  73. RPC[data.func](data)
  74. }
  75. }
  76. }
  77. catch (e){
  78. console.log(e)
  79. }
  80. }
  81. })()
  82. send.onclick = function(){
  83. if (socket && typeof socket.send === 'function')
  84. socket.send(JSON.stringify({func: 'addMessage', nick: nick.value, message: msg.value}))
  85. }