socket.io-parser
Advanced tools
Comparing version 1.1.2 to 2.0.0
2.0.0 / 2014-02-19 | ||
================== | ||
* binary support [kevin-roark] | ||
1.1.2 / 2014-02-11 | ||
@@ -3,0 +8,0 @@ ================== |
215
index.js
@@ -8,3 +8,7 @@ | ||
var json = require('json3'); | ||
var msgpack = require('msgpack-js'); | ||
var isArray = require('isarray'); | ||
var base64 = require('base64-js'); | ||
/** | ||
@@ -28,2 +32,3 @@ * Protocol version. | ||
'EVENT', | ||
'BINARY_EVENT', | ||
'ACK', | ||
@@ -74,10 +79,37 @@ 'ERROR' | ||
/** | ||
* Encode. | ||
* Packet type 'binary event' | ||
* | ||
* @api public | ||
*/ | ||
exports.BINARY_EVENT = 5; | ||
/** | ||
* Encode a packet as a string or buffer, depending on packet type. | ||
* | ||
* @param {Object} packet | ||
* @return {String} encoded | ||
* @return {String | Buffer} encoded | ||
* @api public | ||
*/ | ||
exports.encode = function(obj){ | ||
exports.encode = function(obj, callback){ | ||
debug('encoding packet %j', obj); | ||
if (obj.type === exports.BINARY_EVENT) { | ||
encodeAsBinary(obj, callback); | ||
} | ||
else { | ||
var encoding = encodeAsString(obj); | ||
callback(encoding); | ||
} | ||
}; | ||
/** | ||
* Encode packet as string (used for anything that is not a binary event). | ||
* | ||
* @param {Object} packet | ||
* @return {String} encoded | ||
* @api private | ||
*/ | ||
function encodeAsString(obj) { | ||
var str = ''; | ||
@@ -113,8 +145,85 @@ var nsp = false; | ||
return str; | ||
}; | ||
} | ||
/** | ||
* Decode. | ||
* Encode packet as Buffer (used for binary events). | ||
* | ||
* @param {String} str | ||
* @param {Object} packet | ||
* @return {Buffer} encoded | ||
* @api private | ||
*/ | ||
function encodeAsBinary(obj, callback) { | ||
if (global.Blob || global.File) { | ||
removeBlobs(obj, callback); | ||
} else { | ||
var encoding = msgpack.encode(obj); | ||
callback(encoding); | ||
} | ||
} | ||
/** | ||
* Asynchronously removes Blobs or Files from data via | ||
* FileReaders readAsArrayBuffer method. Used before encoding | ||
* data as msgpack. Calls callback with the blobless data. | ||
* | ||
* @param {Object} data | ||
* @param {Function} callback | ||
* @api private | ||
*/ | ||
function removeBlobs(data, callback) { | ||
function removeBlobsRecursive(obj, curKey, containingObject) { | ||
if (!obj) return obj; | ||
// convert any blob | ||
if ((global.Blob && obj instanceof Blob) || | ||
(global.File && obj instanceof File)) { | ||
pendingBlobs++; | ||
// async filereader | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function() { // this.result == arraybuffer | ||
if (containingObject) { | ||
containingObject[curKey] = this.result; | ||
} | ||
else { | ||
bloblessData = this.result; | ||
} | ||
// if nothing pending its callback time | ||
if(! --pendingBlobs) { | ||
callback(msgpack.encode(bloblessData)); | ||
} | ||
}; | ||
fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer | ||
} | ||
// handle array | ||
if (isArray(obj)) { | ||
for (var i = 0; i < obj.length; i++) { | ||
removeBlobsRecursive(obj[i], i, obj); | ||
} | ||
} else if (obj && 'object' == typeof obj) { // and object | ||
for (var key in obj) { | ||
removeBlobsRecursive(obj[key], key, obj); | ||
} | ||
} | ||
} | ||
var pendingBlobs = 0; | ||
var bloblessData = data; | ||
removeBlobsRecursive(bloblessData); | ||
if (!pendingBlobs) { | ||
callback(msgpack.encode(bloblessData)); | ||
} | ||
} | ||
/** | ||
* Decodes a packet Object (msgpack or string) into | ||
* packet JSON. | ||
* | ||
* @param {Object} obj | ||
* @return {Object} packet | ||
@@ -124,3 +233,28 @@ * @api public | ||
exports.decode = function(str){ | ||
exports.decode = function(obj) { | ||
if ('string' == typeof obj) { | ||
return decodeString(obj); | ||
} | ||
else if (Buffer.isBuffer(obj) || | ||
(global.ArrayBuffer && obj instanceof ArrayBuffer) || | ||
(global.Blob && obj instanceof Blob)) { | ||
return decodeBuffer(obj); | ||
} | ||
else if (obj.base64) { | ||
return decodeBase64(obj.data); | ||
} | ||
else { | ||
throw new Error('Unknown type: ' + obj); | ||
} | ||
} | ||
/** | ||
* Decode a packet String (JSON data) | ||
* | ||
* @param {String} str | ||
* @return {Object} packet | ||
* @api private | ||
*/ | ||
function decodeString(str) { | ||
var p = {}; | ||
@@ -175,2 +309,69 @@ var i = 0; | ||
/** | ||
* Decode binary data packet into JSON packet | ||
* | ||
* @param {Buffer | ArrayBuffer | Blob} buf | ||
* @return {Object} packet | ||
* @api private | ||
*/ | ||
function decodeBuffer(buf) { | ||
return msgpack.decode(buf); | ||
}; | ||
/** | ||
* Decode base64 msgpack string into a packet | ||
* | ||
* @param {String} b64 | ||
* @return {Object} packet | ||
* @api private | ||
*/ | ||
var NSP_SEP = 163; | ||
var EVENT_SEP = 146; | ||
var EVENT_STOP = 216; | ||
function decodeBase64(b64) { | ||
var packet = {type: exports.BINARY_EVENT}; | ||
var bytes = base64.toByteArray(b64); | ||
var nsp = ''; | ||
var eventName = ''; | ||
var data = []; | ||
var currentThing; | ||
for (var i = 0; i < bytes.length; i++) { | ||
var b = bytes[i]; | ||
if (!currentThing) { | ||
if (b == EVENT_SEP && !eventName) { | ||
currentThing = 'ev'; | ||
i += 1; // skip the next thing which is another seperator | ||
} | ||
} | ||
else if (currentThing == 'nsp') { | ||
nsp += String.fromCharCode(b); | ||
} | ||
else if (currentThing == 'ev') { | ||
if (b != EVENT_STOP) { | ||
eventName += String.fromCharCode(b); | ||
} else { | ||
currentThing = 'data'; | ||
i += 2; // next two bytes are 0 and another seperator | ||
} | ||
} | ||
else if (currentThing == 'data') { | ||
if (b != NSP_SEP) { | ||
data.push(b); | ||
} else { | ||
currentThing = 'nsp'; | ||
i += 4; // next three chars are 'nsp', then another seperator | ||
} | ||
} | ||
} | ||
packet.nsp = nsp; | ||
packet.data = [eventName, {base64: true, data: base64.fromByteArray(data)}]; | ||
return packet; | ||
}; | ||
function error(data){ | ||
@@ -177,0 +378,0 @@ return { |
{ | ||
"name": "socket.io-parser", | ||
"version": "1.1.2", | ||
"version": "2.0.0", | ||
"description": "socket.io protocol parser", | ||
"repository":{ | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/LearnBoost/socket.io-protocol.git" | ||
"url": "https://github.com/LearnBoost/socket.io-parser.git" | ||
}, | ||
"browser": { | ||
"msgpack-js": "msgpack-allbrowsers" | ||
}, | ||
"dependencies": { | ||
"debug": "0.7.4", | ||
"json3": "3.3.0" | ||
"msgpack-js": "0.3.0", | ||
"json3": "3.2.6", | ||
"isarray": "0.0.1", | ||
"base64-js": "0.0.6", | ||
"msgpack-allbrowsers": "0.0.1" | ||
}, | ||
@@ -13,0 +20,0 @@ "devDependencies": { |
# socket.io-protocol | ||
# socket.io-parser | ||
[![Build Status](https://secure.travis-ci.org/LearnBoost/socket.io-protocol.png)](http://travis-ci.org/LearnBoost/socket.io-protocol) | ||
This repository contains the protocol specification and JavaScript | ||
parser for the Socket.IO protocol. | ||
## Protocol version | ||
**Current protocol revision:** `1`. | ||
## Parser API | ||
### Parser#encode(Object:packet):String | ||
Encodes a `Packet` object as a string. | ||
### Parser#decode(String:packet):Packet | ||
Returns a `Packet` object for the given string. If a parsing error | ||
occurs the returned packet is an error object. | ||
### Parser#types | ||
Array of packet type keys. | ||
### Packet | ||
Each packet is represented as a vanilla `Object` with a `nsp` key that | ||
indicates what namespace it belongs to (see "Multiplexing") and a | ||
`type` key that can be one of the following: | ||
- `Packet#CONNECT` (`0`) | ||
- `Packet#DISCONNECT` (`1`) | ||
- `Packet#EVENT` (`2`) | ||
- `Packet#ACK` (`3`) | ||
- `Packet#ERROR` (`4`) | ||
#### EVENT | ||
- `data` (`Array`) a list of arguments, the first of which is the event | ||
name. Arguments can contain any type of field that can result of | ||
`JSON` decoding, including objects and arrays of arbitrary size. | ||
- `id` (`Number`) if the `id` identifier is present, it indicates that the | ||
server wishes to be acknowledged of the reception of this event. | ||
#### ACK | ||
- `data` (`Array`) see `EVENT` `data`. | ||
- `id` (`Number`) see `EVENT` `id`. | ||
#### ERROR | ||
- `data` (`Mixed`) error data | ||
## Transport | ||
The socket.io protocol can be delivered over a variety of transports. | ||
[socket.io-client](http://github.com/learnboost/socket.io-client) | ||
is the implementation of the protocol for the browser and Node.JS over | ||
[engine.io-client](http://github.com/learnboost/engine.io-client). | ||
[socket.io](http://github.com/learnboost/socket.io) is the server | ||
implementation of the protocol over | ||
[engine.io](http://github.com/learnboost/engine.io). | ||
## Multiplexing | ||
Socket.IO has built-in multiplexing support, which means that each packet | ||
always belongs to a given `namespace`, identified by a path string (like | ||
`/this`). The corresponding key in the `Packet` object is `nsp`. | ||
When the socket.io transport connection is established, a connection | ||
attempt to the `/` namespace is assumed (ie: the server behaves as if | ||
the client had sent a `CONNECT` packet to the `/` namespace). | ||
In order to support multiplexing of multiple sockets under | ||
the same transport, additional `CONNECT` packets can be sent by the | ||
client to arbitrary namespace URIs (eg: `/another`). | ||
When the server responds with a `CONNECT` packet to the corresponding | ||
namespace, the multiplexed socket is considered connected. | ||
Alternatively, the server can respond with an `ERROR` packet to indicate | ||
a multiplexed socket connection error, such as authentication errors. | ||
The associated error payload varies according to each error, and can | ||
be user-defined. | ||
After a `CONNECT` packet is received by the server for a given `nsp`, | ||
the client can then send and receive `EVENT` packets. If any of the | ||
parties receives an `EVENT` packet with an `id` field, an `ACK` packet is | ||
expected to confirm the reception of said packet. | ||
## License | ||
MIT | ||
[![Build Status](https://secure.travis-ci.org/LearnBoost/socket.io-parser.png)](http://travis-ci.org/LearnBoost/socket.io-parser) | ||
[![NPM version](https://badge.fury.io/js/socket.io-parser.png)](http://badge.fury.io/js/socket.io-parser) |
Sorry, the diff of this file is not supported yet
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
8702
319
6
7
6
1
+ Addedbase64-js@0.0.6
+ Addedisarray@0.0.1
+ Addedmsgpack-allbrowsers@0.0.1
+ Addedmsgpack-js@0.3.0
+ Addedbase64-js@0.0.20.0.6(transitive)
+ Addedbops@0.0.7(transitive)
+ Addedisarray@0.0.1(transitive)
+ Addedjdataview@2.4.5(transitive)
+ Addedjson3@3.2.6(transitive)
+ Addedmsgpack-allbrowsers@0.0.1(transitive)
+ Addedmsgpack-js@0.3.0(transitive)
+ Addedmsgpack-js-browser@0.1.4(transitive)
+ Addedto-utf8@0.0.1(transitive)
- Removedjson3@3.3.0(transitive)
Updatedjson3@3.2.6