123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- let socket;
- function openPromise(){
- let resolve, reject;
- let np = new Promise((ok, fail) => {resolve = ok; reject = fail});
- np.resolve = resolve;
- np.reject = reject;
- return np
- }
- function asynchronize({s, chunkEventName, endEventName}){
- return async function* (){
- const chunks = {};
- const promises = {};
- const clear = i => (delete chunks[i], delete promises[i])
- let chunkCount = 0;
- let promiseCount = 0;
- let end = false;
- if (!('on' in s)){ //no on method in browser
- s.on = function(eventName, callback){ //polyfill
- this['on' + eventName] = callback;
- }
- }
- //check availability of chunk and promise. If any, resolve promise, and clear both from queue
- const chunkAndPromise = i => (i in chunks) &&
- (i in promises) && (
- promises[i].resolve(chunks[i]),
- clear(i))
- s.on(chunkEventName, data => {
- chunks[chunkCount] = data
- chunkAndPromise(chunkCount)
- chunkCount++
- })
- s.on(endEventName, () => {
- end = true;
- for (let i in promises){
- promises[i].reject(new Error('End Of S'))
- }
- })
- while (!end){
- let p;
- promises[promiseCount] = p = openPromise();
- chunkAndPromise(promiseCount)
- promiseCount++;
- yield p; //yield promise outside
- }
- }
- }
- function msg2dom({nick, message, timestamp}){
- const div = document.createElement('div')
- div.innerHTML = `<b>${nick}</b>:${message}`
- return div;
- }
- function userCount2dom({value}){
- const div = document.createElement('div')
- div.innerHTML = `<b>${nick}</b>:${message}`
- return div;
- }
- let RPC = {
- addMessage(data){
- chat.appendChild(msg2dom(data))
- },
- getUserCount({value}){
- chat.appendChild(userCount2dom({value}))
- }
- };
- (async () => {
- while (true){
- try{
- socket = new WebSocket(`ws://${location.host}/`);
- let aGena = asynchronize({s: socket, chunkEventName: 'message', endEventName: 'close'});
- for await (let msg of aGena()){
- let data = JSON.parse(msg.data)
- if (data.func in RPC){
- RPC[data.func](data)
- }
- }
- }
- catch (e){
- console.log(e)
- }
- }
- })()
- send.onclick = function(){
- if (socket && typeof socket.send === 'function')
- socket.send(JSON.stringify({func: 'addMessage', nick: nick.value, message: msg.value}))
- }
|