source: trip-planner-front/node_modules/faye-websocket/lib/faye/websocket/api.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.3 KB
Line 
1'use strict';
2
3var Stream = require('stream').Stream,
4 util = require('util'),
5 driver = require('websocket-driver'),
6 EventTarget = require('./api/event_target'),
7 Event = require('./api/event');
8
9var API = function(options) {
10 options = options || {};
11 driver.validateOptions(options, ['headers', 'extensions', 'maxLength', 'ping', 'proxy', 'tls', 'ca']);
12
13 this.readable = this.writable = true;
14
15 var headers = options.headers;
16 if (headers) {
17 for (var name in headers) this._driver.setHeader(name, headers[name]);
18 }
19
20 var extensions = options.extensions;
21 if (extensions) {
22 [].concat(extensions).forEach(this._driver.addExtension, this._driver);
23 }
24
25 this._ping = options.ping;
26 this._pingId = 0;
27 this.readyState = API.CONNECTING;
28 this.bufferedAmount = 0;
29 this.protocol = '';
30 this.url = this._driver.url;
31 this.version = this._driver.version;
32
33 var self = this;
34
35 this._driver.on('open', function(e) { self._open() });
36 this._driver.on('message', function(e) { self._receiveMessage(e.data) });
37 this._driver.on('close', function(e) { self._beginClose(e.reason, e.code) });
38
39 this._driver.on('error', function(error) {
40 self._emitError(error.message);
41 });
42 this.on('error', function() {});
43
44 this._driver.messages.on('drain', function() {
45 self.emit('drain');
46 });
47
48 if (this._ping)
49 this._pingTimer = setInterval(function() {
50 self._pingId += 1;
51 self.ping(self._pingId.toString());
52 }, this._ping * 1000);
53
54 this._configureStream();
55
56 if (!this._proxy) {
57 this._stream.pipe(this._driver.io);
58 this._driver.io.pipe(this._stream);
59 }
60};
61util.inherits(API, Stream);
62
63API.CONNECTING = 0;
64API.OPEN = 1;
65API.CLOSING = 2;
66API.CLOSED = 3;
67
68API.CLOSE_TIMEOUT = 30000;
69
70var instance = {
71 write: function(data) {
72 return this.send(data);
73 },
74
75 end: function(data) {
76 if (data !== undefined) this.send(data);
77 this.close();
78 },
79
80 pause: function() {
81 return this._driver.messages.pause();
82 },
83
84 resume: function() {
85 return this._driver.messages.resume();
86 },
87
88 send: function(data) {
89 if (this.readyState > API.OPEN) return false;
90 if (!(data instanceof Buffer)) data = String(data);
91 return this._driver.messages.write(data);
92 },
93
94 ping: function(message, callback) {
95 if (this.readyState > API.OPEN) return false;
96 return this._driver.ping(message, callback);
97 },
98
99 close: function(code, reason) {
100 if (code === undefined) code = 1000;
101 if (reason === undefined) reason = '';
102
103 if (code !== 1000 && (code < 3000 || code > 4999))
104 throw new Error("Failed to execute 'close' on WebSocket: " +
105 "The code must be either 1000, or between 3000 and 4999. " +
106 code + " is neither.");
107
108 if (this.readyState < API.CLOSING) {
109 var self = this;
110 this._closeTimer = setTimeout(function() {
111 self._beginClose('', 1006);
112 }, API.CLOSE_TIMEOUT);
113 }
114
115 if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
116
117 this._driver.close(reason, code);
118 },
119
120 _configureStream: function() {
121 var self = this;
122
123 this._stream.setTimeout(0);
124 this._stream.setNoDelay(true);
125
126 ['close', 'end'].forEach(function(event) {
127 this._stream.on(event, function() { self._finalizeClose() });
128 }, this);
129
130 this._stream.on('error', function(error) {
131 self._emitError('Network error: ' + self.url + ': ' + error.message);
132 self._finalizeClose();
133 });
134 },
135
136 _open: function() {
137 if (this.readyState !== API.CONNECTING) return;
138
139 this.readyState = API.OPEN;
140 this.protocol = this._driver.protocol || '';
141
142 var event = new Event('open');
143 event.initEvent('open', false, false);
144 this.dispatchEvent(event);
145 },
146
147 _receiveMessage: function(data) {
148 if (this.readyState > API.OPEN) return false;
149
150 if (this.readable) this.emit('data', data);
151
152 var event = new Event('message', { data: data });
153 event.initEvent('message', false, false);
154 this.dispatchEvent(event);
155 },
156
157 _emitError: function(message) {
158 if (this.readyState >= API.CLOSING) return;
159
160 var event = new Event('error', { message: message });
161 event.initEvent('error', false, false);
162 this.dispatchEvent(event);
163 },
164
165 _beginClose: function(reason, code) {
166 if (this.readyState === API.CLOSED) return;
167 this.readyState = API.CLOSING;
168 this._closeParams = [reason, code];
169
170 if (this._stream) {
171 this._stream.destroy();
172 if (!this._stream.readable) this._finalizeClose();
173 }
174 },
175
176 _finalizeClose: function() {
177 if (this.readyState === API.CLOSED) return;
178 this.readyState = API.CLOSED;
179
180 if (this._closeTimer) clearTimeout(this._closeTimer);
181 if (this._pingTimer) clearInterval(this._pingTimer);
182 if (this._stream) this._stream.end();
183
184 if (this.readable) this.emit('end');
185 this.readable = this.writable = false;
186
187 var reason = this._closeParams ? this._closeParams[0] : '',
188 code = this._closeParams ? this._closeParams[1] : 1006;
189
190 var event = new Event('close', { code: code, reason: reason });
191 event.initEvent('close', false, false);
192 this.dispatchEvent(event);
193 }
194};
195
196for (var method in instance) API.prototype[method] = instance[method];
197for (var key in EventTarget) API.prototype[key] = EventTarget[key];
198
199module.exports = API;
Note: See TracBrowser for help on using the repository browser.