-
Notifications
You must be signed in to change notification settings - Fork 569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#73 Adopt Stream API #147
#73 Adopt Stream API #147
Changes from all commits
ad85391
6ea08de
fb29ff8
9599cc9
cf7dbcb
7766506
1d163f0
233c593
f181a6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,9 +22,14 @@ function Socket (id, server, transport) { | |
this.server = server; | ||
this.upgraded = false; | ||
this.readyState = 'opening'; | ||
this.readable = true; | ||
this.writable = true; | ||
this.writeBuffer = []; | ||
this.packetsFn = []; | ||
this.sentCallbackFn = []; | ||
this.on('error', function(){ | ||
debug('prevented error throwing'); | ||
}); | ||
|
||
this.setTransport(transport); | ||
this.onOpen(); | ||
|
@@ -107,6 +112,26 @@ Socket.prototype.onPacket = function (packet) { | |
} | ||
}; | ||
|
||
|
||
/** | ||
* Pipes output from this Socket to given destination WritableStream. | ||
* | ||
* @param {WritableStream} destination | ||
* @param {Object} optional, does not close destination if options.end is false | ||
* @return {Socket} for chaining | ||
* @api public | ||
*/ | ||
|
||
Socket.prototype.pipe = function (destination, options) { | ||
if (destination.writable) { | ||
this.on('data', destination.write.bind(destination)); | ||
if (!options || options.end !== false) { | ||
this.on('end', destination.end.bind(destination)); | ||
} | ||
} | ||
return this; | ||
} | ||
|
||
/** | ||
* Called upon transport error. | ||
* | ||
|
@@ -226,11 +251,19 @@ Socket.prototype.clearTransport = function () { | |
|
||
Socket.prototype.onClose = function (reason, description) { | ||
if ('closed' != this.readyState) { | ||
if (reason != 'server close' || | ||
reason != 'transport close' || | ||
reason != 'forced close') { | ||
this.emit('error', description); | ||
} | ||
this.packetsFn = []; | ||
this.sentCallbackFn = []; | ||
this.clearTransport(); | ||
this.readyState = 'closed'; | ||
this.emit('close', reason, description); | ||
this.emit('end'); | ||
this.readable = false; | ||
this.writable = false; | ||
} | ||
}; | ||
|
||
|
@@ -347,13 +380,32 @@ Socket.prototype.getAvailableUpgrades = function () { | |
return availableUpgrades; | ||
}; | ||
|
||
|
||
/** | ||
* Writes any queued data and given data before closing the socket. | ||
* | ||
* @param {String} optional, data | ||
* @return {Socket} for chaining | ||
* @api public | ||
*/ | ||
Socket.prototype.end = function (data) { | ||
if (data) { | ||
this.send(data); | ||
} else { | ||
this.flush(); | ||
} | ||
this.close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. send() or flush() doesn't necessarily really flush writeBuffer to the underlying transport, so data may get lost. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Close does not close the immediately, so no data will be lost. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For websocket, close() immediately invokes the close method of the underlying socket. And at the time, this.writable might be false, causing the send() or flush() buffers the data only in this.writeBuffer, not into the underlying socket. |
||
return this; | ||
} | ||
|
||
/** | ||
* Closes the socket and underlying transport. | ||
* | ||
* @return {Socket} for chaining | ||
* @api public | ||
*/ | ||
|
||
Socket.prototype.destroy = | ||
Socket.prototype.close = function () { | ||
if ('open' == this.readyState) { | ||
this.readyState = 'closing'; | ||
|
@@ -362,4 +414,19 @@ Socket.prototype.close = function () { | |
self.onClose('forced close'); | ||
}); | ||
} | ||
return this; | ||
}; | ||
|
||
|
||
/** | ||
* Closes the socket and underlying transport once the queue is drained. | ||
* | ||
* @return {Socket} for chaining | ||
* @api public | ||
*/ | ||
|
||
Socket.prototype.destroySoon = function () { | ||
this.on('drain', this.close.bind(this)); | ||
this.flush(); | ||
return this; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use the real Stream#pipe function from node? - a lot of development work went into getting it right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @xixixao