websocket-stream
Advanced tools
Comparing version 0.6.0 to 1.0.0
@@ -1,2 +0,1 @@ | ||
var WebSocketServer = require('ws').Server | ||
@@ -6,8 +5,6 @@ var http = require('http') | ||
var server = null | ||
var fake = require('./fake-server') | ||
var port = module.exports.port = fake.port | ||
var port = module.exports.port = 8343 | ||
var url = module.exports.url = 'ws://localhost:' + module.exports.port | ||
module.exports.url = fake.url | ||
module.exports.start = function(opts, cb) { | ||
@@ -14,0 +11,0 @@ if (server) { |
142
index.js
@@ -1,97 +0,63 @@ | ||
var through = require('through') | ||
var isBuffer = require('isbuffer') | ||
var WebSocketPoly = require('ws') | ||
var through = require('through2') | ||
var duplexify = require('duplexify') | ||
var WS = require('ws') | ||
function WebsocketStream(server, options) { | ||
if (!(this instanceof WebsocketStream)) return new WebsocketStream(server, options) | ||
module.exports = WebSocketStream | ||
this.stream = through(this.write.bind(this), this.end.bind(this)) | ||
this.stream.websocketStream = this | ||
this.options = options || {} | ||
this._buffer = [] | ||
if (typeof server === "object") { | ||
this.ws = server | ||
this.ws.on('message', this.onMessage.bind(this)) | ||
this.ws.on('error', this.onError.bind(this)) | ||
this.ws.on('close', this.onClose.bind(this)) | ||
this.ws.on('open', this.onOpen.bind(this)) | ||
if (this.ws.readyState === 1) this._open = true | ||
function WebSocketStream(target, options) { | ||
if (!options) options = {} | ||
var stream, socket | ||
var proxy = through(socketWrite, socketEnd) | ||
// use existing WebSocket object that was passed in | ||
if (typeof target === 'object') { | ||
socket = target | ||
// otherwise make a new one | ||
} else { | ||
var opts = (process.title === 'browser') ? this.options.protocol : this.options | ||
this.ws = new WebSocketPoly(server, opts) | ||
this.ws.binaryType = this.options.binaryType || 'arraybuffer' | ||
this.ws.onmessage = this.onMessage.bind(this) | ||
this.ws.onerror = this.onError.bind(this) | ||
this.ws.onclose = this.onClose.bind(this) | ||
this.ws.onopen = this.onOpen.bind(this) | ||
socket = new WS(target, options) | ||
socket.binaryType = 'arraybuffer' | ||
} | ||
// was already open when passed in | ||
if (socket.readyState === 1) { | ||
stream = proxy | ||
} else { | ||
stream = duplexify() | ||
socket.addEventListener("open", onready) | ||
} | ||
this.stream.destroy = this.destroy.bind(this) | ||
return this.stream | ||
} | ||
module.exports = WebsocketStream | ||
module.exports.WebsocketStream = WebsocketStream | ||
WebsocketStream.prototype.destroy = function() { | ||
this.ws.close() | ||
} | ||
WebsocketStream.prototype.onMessage = function(e) { | ||
var data = e | ||
if (typeof data.data !== 'undefined') data = data.data | ||
// type must be a Typed Array (ArrayBufferView) | ||
var type = this.options.type | ||
if (type && data instanceof ArrayBuffer) data = new type(data) | ||
socket.addEventListener("close", onclose) | ||
socket.addEventListener("error", onerror) | ||
socket.addEventListener("message", onmessage) | ||
function socketWrite(chunk, enc, next) { | ||
socket.send(chunk) | ||
next() | ||
} | ||
this.stream.queue(data) | ||
} | ||
WebsocketStream.prototype.onError = function(err) { | ||
this.stream.emit('error', err) | ||
} | ||
WebsocketStream.prototype.onClose = function(err) { | ||
if (this._destroy) return | ||
this.stream.emit('end') | ||
this.stream.emit('close') | ||
} | ||
WebsocketStream.prototype.onOpen = function(err) { | ||
if (this._destroy) return | ||
this._open = true | ||
for (var i = 0; i < this._buffer.length; i++) { | ||
this._write(this._buffer[i]) | ||
function socketEnd(done) { | ||
socket.close() | ||
done() | ||
} | ||
this._buffer = undefined | ||
this.stream.emit('open') | ||
this.stream.emit('connect') | ||
if (this._end) this.ws.close() | ||
} | ||
WebsocketStream.prototype.write = function(data) { | ||
if (!this._open) { | ||
this._buffer.push(data) | ||
} else { | ||
this._write(data) | ||
function onready() { | ||
stream.setReadable(proxy) | ||
stream.setWritable(proxy) | ||
} | ||
function onclose() { | ||
stream.destroy() | ||
} | ||
function onerror(err) { | ||
stream.destroy(err) | ||
} | ||
function onmessage(event) { | ||
var data = event.data | ||
if (data instanceof ArrayBuffer) data = new Buffer(new Uint8Array(data)) | ||
proxy.push(data) | ||
} | ||
return stream | ||
} | ||
WebsocketStream.prototype._write = function(data) { | ||
if (this.ws.readyState == 1) | ||
// we are connected | ||
typeof WebSocket != 'undefined' && this.ws instanceof WebSocket | ||
? this.ws.send(data) | ||
: this.ws.send(data, { binary : isBuffer(data) }) | ||
else | ||
this.stream.emit('error', 'Not connected') | ||
} | ||
WebsocketStream.prototype.end = function(data) { | ||
if (data !== undefined) this.stream.queue(data) | ||
if (this._open) this.ws.close() | ||
this._end = true | ||
} |
{ | ||
"name": "websocket-stream", | ||
"version": "0.6.0", | ||
"description": "websockets with the node stream api. works in browser and node", | ||
"version": "1.0.0", | ||
"description": "Use websockets with the node streams API. Works in browser and node", | ||
"scripts": { | ||
"start": "browserify demo.js -o demo-bundle.js && node demo-server.js", | ||
"test": "node test.js", | ||
"echo": "node echo-server.js" | ||
"start": "beefy test-client.js" | ||
}, | ||
@@ -26,33 +25,16 @@ "repository": { | ||
"dependencies": { | ||
"isbuffer": "0.0.0", | ||
"ws": "~0.4.30", | ||
"through": "~2.3.4" | ||
"duplexify": "^3.2.0", | ||
"through2": "^0.6.1", | ||
"ws": "^0.4.32", | ||
"xtend": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"el-streamo": "1.0.0", | ||
"ecstatic": "0.4.2", | ||
"browserify": "2.14.1", | ||
"stringstream": "0.0.4", | ||
"tape": "~1.0.4" | ||
"beefy": "^2.1.1", | ||
"browserify": "^5.11.1", | ||
"tape": "^2.14.0" | ||
}, | ||
"optionalDependencies": {}, | ||
"engines": { | ||
"node": ">=0.8" | ||
}, | ||
"browser": { | ||
"./echo-server.js": "./fake-server.js" | ||
}, | ||
"testling": { | ||
"files": "test.js", | ||
"server": "node echo-server.js", | ||
"browsers": [ | ||
"ie/6..latest", | ||
"chrome/20..latest", | ||
"firefox/10..latest", | ||
"safari/latest", | ||
"opera/11.0..latest", | ||
"iphone/6", | ||
"ipad/6" | ||
] | ||
} | ||
} |
# websocket-stream | ||
npm install websocket-stream | ||
[![NPM](https://nodei.co/npm/websocket-stream.png?global=true)](https://nodei.co/npm/websocket-stream/) | ||
use HTML5 [websockets](https://developer.mozilla.org/en-US/docs/WebSockets) the node way -- with streams | ||
Use HTML5 [websockets](https://developer.mozilla.org/en-US/docs/WebSockets) using the Node Streams API. Works in Node or in Browsers. | ||
# in the browser | ||
### In the browser | ||
you can use [browserify](http://github.com/substack/node-browserify) to package this module for browser use. | ||
You can use [browserify](http://github.com/substack/node-browserify) to package this module for browser use. | ||
@@ -17,16 +17,8 @@ ```javascript | ||
`ws` is a stream and speaks stream events: `data`, `error` and `end`. that means you can pipe output to anything that accepts streams. you can also pipe data into streams (such as a webcam feed or audio data) | ||
In the example above `ws` is a duplex stream. That means you can pipe output to anything that accepts streams. You can also pipe data into streams (such as a webcam feed or audio data). | ||
### browserify steps | ||
```javascript | ||
npm install -g browserify // install browserify | ||
cd node_modules/websocket-stream | ||
npm install . // install dev dependencies | ||
browserify index.js -s websocket-stream > websocket-stream.js // require websocket-stream.js in your client-side app | ||
``` | ||
### On the server | ||
# on the server | ||
Using the [`ws`](http://npmjs.org/ws) module you can make a websocket server and use this module to get websocket streams on the server: | ||
using the [`ws`](http://npmjs.org/ws) module you can make a websocket server and use this module to get websocket streams on the server: | ||
```javascript | ||
@@ -42,27 +34,16 @@ var WebSocketServer = require('ws').Server | ||
## options | ||
## run the tests | ||
pass in options as the second argument like this: | ||
### server-side tests | ||
```js | ||
websocketStream('ws://foobar', { type: someTypedArray }) | ||
// e.g. {type: Uint8Array} means you'll get Uint8Arrays back instead of ArrayBuffers | ||
``` | ||
npm test | ||
possible options are... | ||
```js | ||
{ | ||
protocol: // optional, string, specify websocket protocol | ||
type: // optional, TypedArray object, wraps the ArrayBuffer before emitting | ||
} | ||
``` | ||
### binary sockets | ||
### client side tests | ||
To send binary data just write a [Buffer](nodejs.org/api/buffer.html) or [TypedArray](https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays) to the stream. | ||
On the other end you will receive [Buffer](nodejs.org/api/buffer.html) instances if it's the server and [ArrayBuffer](https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays/ArrayBuffer) instances if it's the client. The client will default to `ArrayBuffer` objects but can also be configured to receive `Blob`s. | ||
first start the echo server by running `node test-server.js` | ||
If you write binary data to a websocket on the server, the client will receive binary objects. Same thing goes for strings. | ||
then run `npm start` and open `localhost:9966` in your browser and open the Dev Tools console to see test output | ||
@@ -69,0 +50,0 @@ ## license |
@@ -13,3 +13,4 @@ var test = require('tape') | ||
client.on('data', function(data) { | ||
t.equal(data, 'hello world') | ||
t.ok(Buffer.isBuffer(data), 'is a buffer') | ||
t.equal(data.toString(), 'hello world') | ||
client.end() | ||
@@ -49,3 +50,3 @@ echo.stop(function() { | ||
test('passes options to websocket constructor', function(t) { | ||
t.plan(2) | ||
t.plan(3) | ||
@@ -65,3 +66,4 @@ opts = { | ||
client.on('data', function(data) { | ||
t.equal(data, 'hello world') | ||
t.ok(Buffer.isBuffer(data), 'is a buffer') | ||
t.equal(data.toString(), 'hello world') | ||
client.end() | ||
@@ -68,0 +70,0 @@ echo.stop(function() {}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
3
1
0
2
8210
4
10
162
51
+ Addedduplexify@^3.2.0
+ Addedthrough2@^0.6.1
+ Addedxtend@^4.0.0
+ Addedcore-util-is@1.0.3(transitive)
+ Addedduplexify@3.7.1(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@0.0.11.0.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedreadable-stream@1.0.342.3.8(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedstream-shift@1.0.3(transitive)
+ Addedstring_decoder@0.10.311.1.1(transitive)
+ Addedthrough2@0.6.5(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedxtend@4.0.2(transitive)
- Removedisbuffer@0.0.0
- Removedthrough@~2.3.4
- Removedisbuffer@0.0.0(transitive)
- Removedthrough@2.3.8(transitive)
Updatedws@^0.4.32