UNPKG

ember-websockets

Version:

EmberJS WebSockets addon for Ember-CLI apps.

96 lines (78 loc) 2.83 kB
import Service from '@ember/service'; import { set, get, computed } from '@ember/object'; import WebsocketProxy from '../helpers/websocket-proxy'; import { normalizeURL, cleanURL } from '../helpers'; export default class WebSocketService extends Service { /* A hash of open websocket connections. This allows multiple components to share the same connection. { 'websocket-url': WebSocket Proxy object } */ @computed() get sockets() { return {}; } /* socketFor returns a websocket proxy object. On this object there is a property `socket` which contains the actual websocket object. This websocket object is cached based off of the url meaning multiple requests for the same socket will return the same object. */ socketFor(url, protocols = []) { /* Websockets allows either a string or array of strings to be passed as the second argument. Normalize both cases into an array of strings so we can just deal with arrays. */ if (typeof protocols === 'string') { protocols = [protocols]; } /* Normalize the url as native websockets add a / to the end of the url: http://example.com:8000 becomes: http://example.com:8000/ Since the url will be used as a key will need to make sure that it does not contain '.' as it will throw ember off */ const normalizedUrl = normalizeURL(url); const cleanedUrl = cleanURL(normalizedUrl); /* */ const existingProxy = get(this, `sockets.${cleanedUrl}`); if (existingProxy && this.isWebSocketOpen(existingProxy.socket)) { return existingProxy; } /* we can get to this place if the websocket has been closed and we are trying to reopen or we are creating a proxy for the first time */ const newWebSocket = this.createSocket(normalizedUrl, protocols); if (existingProxy) { /* If there is an existing socket in place we simply update the websocket object and not the whole proxy as we dont want to destroy the previous listeners. */ set(existingProxy, 'socket', newWebSocket); return existingProxy; } const newProxy = this.createProxy(newWebSocket, protocols); set(this, `sockets.${cleanedUrl}`, newProxy); return newProxy; } closeSocketFor(url) { const cleanedUrl = cleanURL(normalizeURL(url)); const existingSocket = get(this, `sockets.${cleanedUrl}`); if (existingSocket) { existingSocket.socket.close(); } delete this.sockets[cleanedUrl]; } isWebSocketOpen(websocket) { return websocket.readyState !== WebSocket.CLOSED; } createSocket(url, options) { return new WebSocket(url, options); } createProxy(socket, protocols) { return WebsocketProxy.create({ content: this, protocols, socket }); } }