100 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| var utils = require('../utils/event')
 | |
|   , urlUtils = require('../utils/url')
 | |
|   , inherits = require('inherits')
 | |
|   , EventEmitter = require('events').EventEmitter
 | |
|   , WebsocketDriver = require('./driver/websocket')
 | |
|   ;
 | |
| 
 | |
| var debug = function() {};
 | |
| if (process.env.NODE_ENV !== 'production') {
 | |
|   debug = require('debug')('sockjs-client:websocket');
 | |
| }
 | |
| 
 | |
| function WebSocketTransport(transUrl, ignore, options) {
 | |
|   if (!WebSocketTransport.enabled()) {
 | |
|     throw new Error('Transport created when disabled');
 | |
|   }
 | |
| 
 | |
|   EventEmitter.call(this);
 | |
|   debug('constructor', transUrl);
 | |
| 
 | |
|   var self = this;
 | |
|   var url = urlUtils.addPath(transUrl, '/websocket');
 | |
|   if (url.slice(0, 5) === 'https') {
 | |
|     url = 'wss' + url.slice(5);
 | |
|   } else {
 | |
|     url = 'ws' + url.slice(4);
 | |
|   }
 | |
|   this.url = url;
 | |
| 
 | |
|   this.ws = new WebsocketDriver(this.url, [], options);
 | |
|   this.ws.onmessage = function(e) {
 | |
|     debug('message event', e.data);
 | |
|     self.emit('message', e.data);
 | |
|   };
 | |
|   // Firefox has an interesting bug. If a websocket connection is
 | |
|   // created after onunload, it stays alive even when user
 | |
|   // navigates away from the page. In such situation let's lie -
 | |
|   // let's not open the ws connection at all. See:
 | |
|   // https://github.com/sockjs/sockjs-client/issues/28
 | |
|   // https://bugzilla.mozilla.org/show_bug.cgi?id=696085
 | |
|   this.unloadRef = utils.unloadAdd(function() {
 | |
|     debug('unload');
 | |
|     self.ws.close();
 | |
|   });
 | |
|   this.ws.onclose = function(e) {
 | |
|     debug('close event', e.code, e.reason);
 | |
|     self.emit('close', e.code, e.reason);
 | |
|     self._cleanup();
 | |
|   };
 | |
|   this.ws.onerror = function(e) {
 | |
|     debug('error event', e);
 | |
|     self.emit('close', 1006, 'WebSocket connection broken');
 | |
|     self._cleanup();
 | |
|   };
 | |
| }
 | |
| 
 | |
| inherits(WebSocketTransport, EventEmitter);
 | |
| 
 | |
| WebSocketTransport.prototype.send = function(data) {
 | |
|   var msg = '[' + data + ']';
 | |
|   debug('send', msg);
 | |
|   this.ws.send(msg);
 | |
| };
 | |
| 
 | |
| WebSocketTransport.prototype.close = function() {
 | |
|   debug('close');
 | |
|   var ws = this.ws;
 | |
|   this._cleanup();
 | |
|   if (ws) {
 | |
|     ws.close();
 | |
|   }
 | |
| };
 | |
| 
 | |
| WebSocketTransport.prototype._cleanup = function() {
 | |
|   debug('_cleanup');
 | |
|   var ws = this.ws;
 | |
|   if (ws) {
 | |
|     ws.onmessage = ws.onclose = ws.onerror = null;
 | |
|   }
 | |
|   utils.unloadDel(this.unloadRef);
 | |
|   this.unloadRef = this.ws = null;
 | |
|   this.removeAllListeners();
 | |
| };
 | |
| 
 | |
| WebSocketTransport.enabled = function() {
 | |
|   debug('enabled');
 | |
|   return !!WebsocketDriver;
 | |
| };
 | |
| WebSocketTransport.transportName = 'websocket';
 | |
| 
 | |
| // In theory, ws should require 1 round trip. But in chrome, this is
 | |
| // not very stable over SSL. Most likely a ws connection requires a
 | |
| // separate SSL connection, in which case 2 round trips are an
 | |
| // absolute minumum.
 | |
| WebSocketTransport.roundTrips = 2;
 | |
| 
 | |
| module.exports = WebSocketTransport;
 |