socket.io-stream
Advanced tools
Comparing version 0.6.1 to 0.7.0
@@ -9,2 +9,9 @@ var Socket = require('./socket'); | ||
/** | ||
* Expose Node Buffer for browser. | ||
* | ||
* @api public | ||
*/ | ||
exports.Buffer = Buffer; | ||
/** | ||
* Expose Socket constructor. | ||
@@ -17,2 +24,9 @@ * | ||
/** | ||
* Expose IOStream constructor. | ||
* | ||
* @api public | ||
*/ | ||
exports.IOStream = IOStream; | ||
/** | ||
* Forces base 64 encoding when emitting. Must be set to true for Socket.IO v0.9 or lower. | ||
@@ -19,0 +33,0 @@ * |
var util = require('util'); | ||
var Duplex = require('stream').Duplex; | ||
var bind = require('component-bind'); | ||
var uuid = require('./uuid'); | ||
var debug = require('debug')('socket.io-stream:iostream'); | ||
@@ -24,3 +25,4 @@ | ||
this.id = null; | ||
this.options = options; | ||
this.id = uuid(); | ||
this.socket = null; | ||
@@ -27,0 +29,0 @@ |
var util = require('util'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var bind = require('component-bind'); | ||
var IOStream = require('./iostream'); | ||
var uuid = require('./uuid'); | ||
var bind = require('component-bind'); | ||
var parser = require('./parser'); | ||
var debug = require('debug')('socket.io-stream:socket'); | ||
@@ -47,2 +47,4 @@ var emit = EventEmitter.prototype.emit; | ||
this.streams = {}; | ||
this.encoder = new parser.Encoder(); | ||
this.decoder = new parser.Decoder(); | ||
@@ -57,2 +59,5 @@ var eventName = exports.event; | ||
sio.on('disconnect', bind(this, '_ondisconnect')); | ||
this.encoder.on('stream', bind(this, '_onencode')); | ||
this.decoder.on('stream', bind(this, '_ondecode')); | ||
} | ||
@@ -81,3 +86,3 @@ | ||
Socket.prototype.on = function(type, options, listener) { | ||
Socket.prototype.on = function(type, listener) { | ||
if (~exports.events.indexOf(type)) { | ||
@@ -87,7 +92,3 @@ return on.apply(this, arguments); | ||
if ('function' == typeof options) { | ||
listener = options; | ||
options = null; | ||
} | ||
this._onstream(type, options, listener); | ||
this._onstream(type, listener); | ||
return this; | ||
@@ -105,29 +106,7 @@ }; | ||
var args = slice.call(arguments, 1) | ||
, pos = [] | ||
, sio = this.sio; | ||
var args = slice.call(arguments, 1); | ||
var sio = this.sio; | ||
args = args.map(function(stream, i) { | ||
if (!(stream instanceof IOStream)) { | ||
return stream; | ||
} | ||
if (stream.socket || stream.destroyed) { | ||
throw new Error('stream has already been sent.'); | ||
} | ||
// keep stream positions of args. | ||
pos.push(i); | ||
// Generate | ||
var id = uuid(); | ||
this.streams[id] = stream; | ||
stream.id = id; | ||
stream.socket = this; | ||
// represent a stream in an id. | ||
return id; | ||
}, this); | ||
sio.emit.apply(sio, [exports.event, type, pos].concat(args)); | ||
args = this.encoder.encode(args); | ||
sio.emit.apply(sio, [exports.event, type].concat(args)); | ||
}; | ||
@@ -150,8 +129,10 @@ | ||
Socket.prototype._write = function(id, chunk, encoding, callback) { | ||
if (this.forceBase64) { | ||
encoding = 'base64'; | ||
chunk = chunk.toString(encoding); | ||
} else if (Buffer.isBuffer(chunk) && !global.Buffer) { | ||
// socket.io can't handle Buffer when using browserify. | ||
chunk = chunk.toArrayBuffer(); | ||
if (Buffer.isBuffer(chunk)) { | ||
if (this.forceBase64) { | ||
encoding = 'base64'; | ||
chunk = chunk.toString(encoding); | ||
} else if (!global.Buffer) { | ||
// socket.io can't handle Buffer when using browserify. | ||
chunk = chunk.toArrayBuffer(); | ||
} | ||
} | ||
@@ -173,3 +154,2 @@ this.sio.emit(exports.event + '-write', id, chunk, encoding, callback); | ||
* @param {String} event type | ||
* @param {Object} options for streams | ||
* @param {Function} listener | ||
@@ -179,3 +159,3 @@ * | ||
*/ | ||
Socket.prototype._onstream = function(type, options, listener) { | ||
Socket.prototype._onstream = function(type, listener) { | ||
if ('function' != typeof listener) { | ||
@@ -185,24 +165,7 @@ throw TypeError('listener must be a function'); | ||
function onstream(pos) { | ||
function onstream() { | ||
debug('new streams'); | ||
var args = slice.call(arguments, 1); | ||
var args = slice.call(arguments); | ||
args = args.map(function(id, i) { | ||
if (!~pos.indexOf(i)) { | ||
// arg is not a stream. | ||
return id; | ||
} | ||
if (this.streams[id]) { | ||
this._error(id, 'id already exists'); | ||
return; | ||
} | ||
var stream = this.streams[id] = new IOStream(options); | ||
stream.id = id; | ||
stream.socket = this; | ||
return stream; | ||
}, this); | ||
args = this.decoder.decode(args); | ||
listener.apply(this, args); | ||
@@ -282,2 +245,27 @@ } | ||
Socket.prototype._onencode = function(stream) { | ||
if (stream.socket || stream.destroyed) { | ||
throw new Error('stream has already been sent.'); | ||
} | ||
var id = stream.id; | ||
if (this.streams[id]) { | ||
throw new Error('Encoded stream already exists: ' + id); | ||
} | ||
this.streams[id] = stream; | ||
stream.socket = this; | ||
}; | ||
Socket.prototype._ondecode = function(stream) { | ||
var id = stream.id; | ||
if (this.streams[id]) { | ||
this._error(id, new Error('Decoded stream already exists: ' + id)); | ||
return; | ||
} | ||
this.streams[id] = stream; | ||
stream.socket = this; | ||
}; | ||
Socket.prototype.cleanup = function(id) { | ||
@@ -284,0 +272,0 @@ delete this.streams[id]; |
{ | ||
"name": "socket.io-stream", | ||
"version": "0.6.1", | ||
"version": "0.7.0", | ||
"description": "stream for socket.io", | ||
@@ -38,5 +38,5 @@ "author": "Naoyuki Kanezawa <naoyuki.kanezawa@gmail.com>", | ||
"blob": "0.0.4", | ||
"browserify": "~9.0.7", | ||
"browserify": "~9.0.8", | ||
"expect.js": "~0.3.1", | ||
"mocha": "~2.2.1", | ||
"mocha": "~2.2.4", | ||
"socket.io": "~1.3.5", | ||
@@ -43,0 +43,0 @@ "socket.io-client": "~1.3.4", |
# Socket.IO stream | ||
[![Build Status](https://travis-ci.org/nkzawa/socket.io-stream.png?branch=master)](https://travis-ci.org/nkzawa/socket.io-stream) | ||
[![NPM version](https://badge.fury.io/js/socket.io-stream.png)](http://badge.fury.io/js/socket.io-stream) | ||
This is the module for bidirectional binary data transfer with Stream 2 API through [Socket.IO](https://github.com/LearnBoost/socket.io). | ||
This is the module for bidirectional binary data transfer with Stream API through [Socket.IO](https://github.com/LearnBoost/socket.io). | ||
## Installation | ||
$ npm install socket.io-stream | ||
npm install socket.io-stream | ||
## Usage | ||
If you are not familiar with Stream API, be sure to check out [the docs](http://nodejs.org/api/stream.html). | ||
I also recommend checking out the awesome [Stream Handbook](https://github.com/substack/stream-handbook): | ||
I also recommend checking out the awesome [Stream Handbook](https://github.com/substack/stream-handbook). | ||
For streaming between servers and clients, you must send stream instances first. | ||
For streaming between server and client, you will send stream instances first. | ||
To receive streams, you just wrap `socket` with `socket.io-stream`, then listen any events as usual. | ||
Server: | ||
```js | ||
@@ -31,5 +35,6 @@ var io = require('socket.io').listen(80); | ||
`createStream()` will return a new stream which can be sent by `emit`. | ||
`createStream()` returns a new stream which can be sent by `emit()`. | ||
Client: | ||
```js | ||
@@ -61,2 +66,3 @@ var io = require('socket.io-client'); | ||
### Browser | ||
This module can be used on the browser. To do so, just copy a file to a public directory. | ||
@@ -66,3 +72,3 @@ | ||
You can also use [browserify](http://github.com/substack/node-browserify) to build manually. | ||
You can also use [browserify](http://github.com/substack/node-browserify) to create your own bundle. | ||
@@ -96,2 +102,3 @@ $ npm install browserify -g | ||
#### Upload progress | ||
You can track upload progress like the following: | ||
@@ -112,5 +119,6 @@ | ||
### Supporting Socket.IO 0.9 | ||
You have set `forceBase64` option `true` when using on socket.io v0.9.x. | ||
### Socket.IO v0.9 support | ||
You have to set `forceBase64` option `true` when using the library with socket.io v0.9.x. | ||
```js | ||
@@ -124,2 +132,3 @@ ss.forceBase64 = true; | ||
### ss(sio) | ||
- sio `socket.io Socket` A socket of Socket.IO, both for client and server | ||
@@ -131,30 +140,38 @@ - return `Socket` | ||
### socket.emit(event, [arg1], [arg2], [...]) | ||
- event `String` The event name | ||
Emit an `event` with variable args including at least a stream. | ||
Emit an `event` with variable number of arguments including at least a stream. | ||
```js | ||
ss(socket).emit('myevent', stream, {name: 'thefilename'}, function() { ... }); | ||
// send some streams at a time. | ||
ss(socket).emit('multiple-streams', stream1, stream2); | ||
// as members of array or object. | ||
ss(socket).emit('flexible', [stream1, { foo: stream2 }]); | ||
``` | ||
### socket.on(event, [options], listener) | ||
### socket.on(event, listener) | ||
- event `String` The event name | ||
- options `Object` options for received Streams | ||
- highWaterMark `Number` | ||
- encoding `String` | ||
- decodeStrings `Boolean` | ||
- objectMode `Boolean` | ||
- listener `Function` The event handler function | ||
Add a `listener` for `event`. `listener` will take streams with any data as arguments. `options` is an object for streams. | ||
Add a `listener` for `event`. `listener` will take stream(s) with any data as arguments. | ||
```js | ||
ss(socket).on('myevent', function(stream, data, callback) { ... }); | ||
// with options | ||
ss(socket).on('any', {highWaterMark: 64 * 1024}, function(stream) { ... }); | ||
// access stream options | ||
ss(socket).on('foo', function(stream) { | ||
if (stream.options && stream.options.highWaterMark > 1024) { | ||
console.error('Too big highWaterMark.'); | ||
return; | ||
} | ||
}); | ||
``` | ||
### ss.createStream([options]) | ||
- options `Object` | ||
@@ -165,2 +182,3 @@ - highWaterMark `Number` | ||
- objectMode `Boolean` | ||
- allowHalfOpen `Boolean` if `true`, then the stream won't automatically close when the other endpoint ends. Default to `false`. | ||
- return `Duplex Stream` | ||
@@ -172,5 +190,13 @@ | ||
var stream = ss.createStream(); | ||
// with options | ||
var stream = ss.createStream({ | ||
highWaterMark: 1024, | ||
objectMode: true, | ||
allowHalfOpen: true | ||
}); | ||
``` | ||
### ss.createBlobReadStream(blob, [options]) | ||
- options `Object` | ||
@@ -188,4 +214,13 @@ - highWaterMark `Number` | ||
### ss.Buffer | ||
Node Buffer class to use on browser, which is exposed for convenience. On Node environment, uou should just use normal `Buffer`. | ||
```js | ||
var stream = ss.createStream(); | ||
stream.write(new ss.Buffer([0, 1, 2])); | ||
``` | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
194629
14
5917
217