mirror of
https://github.com/socketio/socket.io.git
synced 2026-04-30 03:00:39 -04:00
@@ -3,11 +3,16 @@ server: ./test/support/server.js
|
||||
browsers:
|
||||
- name: chrome
|
||||
version: 29..latest
|
||||
# Firefox disabled for now because it can cause infinite wait loops when
|
||||
# running any tests
|
||||
# - name: firefox
|
||||
# version: latest
|
||||
- name: safari
|
||||
version: latest
|
||||
- name: ie
|
||||
version: 6..latest
|
||||
version: 10
|
||||
platform: Windows 2012
|
||||
- name: ie
|
||||
version: [6..9, latest]
|
||||
- name: iphone
|
||||
version: oldest..latest
|
||||
|
||||
2
Makefile
2
Makefile
@@ -18,4 +18,4 @@ test-cov:
|
||||
--reporter $(REPORTER) \
|
||||
$(TESTS)
|
||||
|
||||
.PHONY: test
|
||||
.PHONY: test build
|
||||
|
||||
34
README.md
34
README.md
@@ -56,6 +56,23 @@ browserify app.js > bundle.js
|
||||
<script src="/path/to/bundle.js"></script>
|
||||
```
|
||||
|
||||
### Sending and receiving binary
|
||||
|
||||
```html
|
||||
<script src="/path/to/engine.io.js"></script>
|
||||
<script>
|
||||
var socket = new eio.Socket('ws://localhost/');
|
||||
socket.binaryType = 'blob'; // receives Blob instead of ArrayBuffer (default)
|
||||
socket.on('open', function () {
|
||||
socket.send(new Int8Array(5));
|
||||
socket.on('message', function (data) {
|
||||
// data instanceof Blob => true when receiving binary
|
||||
});
|
||||
socket.on('close', function () { });
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### Node.JS
|
||||
|
||||
Add `engine.io-client` to your `package.json` and then:
|
||||
@@ -78,6 +95,14 @@ socket.onopen = function(){
|
||||
- Easy to debug
|
||||
- Easy to unit test
|
||||
- Runs inside HTML5 WebWorker
|
||||
- Can send and receive binary data
|
||||
- Receives as ArrayBuffer or Blob when in browser, and Buffer or ArrayBuffer
|
||||
in Node
|
||||
- When XHR2 or WebSockets are used, binary is emitted directly. Otherwise
|
||||
binary is encoded into base64 strings, and decoded when binary types are
|
||||
supported.
|
||||
- With browsers that don't support ArrayBuffer, an object { base64: true,
|
||||
data: dataAsBase64String } is emitted in onmessage
|
||||
|
||||
## API
|
||||
|
||||
@@ -95,6 +120,9 @@ Exposed as `eio` in the browser standalone build.
|
||||
- `message` event handler
|
||||
- `onclose` (_Function_)
|
||||
- `message` event handler
|
||||
- `binaryType` _(String)_ : can be set to 'arraybuffer' or 'blob' in browsers,
|
||||
and `buffer` or `arraybuffer` in Node. Blob is only used in browser if it's
|
||||
supported.
|
||||
|
||||
#### Events
|
||||
|
||||
@@ -103,7 +131,8 @@ Exposed as `eio` in the browser standalone build.
|
||||
- `message`
|
||||
- Fired when data is received from the server.
|
||||
- **Arguments**
|
||||
- `String`: utf-8 encoded data
|
||||
- `String` | `ArrayBuffer`: utf-8 encoded data or ArrayBuffer containing
|
||||
binary data
|
||||
- `close`
|
||||
- Fired upon disconnection. In compliance with the WebSocket API spec, this event may be
|
||||
fired even if the `open` event does not occur (i.e. due to connection error or `close()`).
|
||||
@@ -130,6 +159,7 @@ Exposed as `eio` in the browser standalone build.
|
||||
- `upgrade` (`Boolean`): defaults to true, whether the client should try
|
||||
to upgrade the transport from long-polling to something better.
|
||||
- `forceJSONP` (`Boolean`): forces JSONP for polling transport.
|
||||
- `forceBase64` (`Boolean`): forces base 64 encoding for polling transport even when XHR2 responseType is available and WebSocket even if the used standard supports binary.
|
||||
- `timestampRequests` (`Boolean`): whether to add the timestamp with
|
||||
each transport request. Note: this is ignored if the browser is
|
||||
IE or Android, in which case requests are always stamped (`false`)
|
||||
@@ -150,7 +180,7 @@ Exposed as `eio` in the browser standalone build.
|
||||
- `send`
|
||||
- Sends a message to the server
|
||||
- **Parameters**
|
||||
- `String`: data to send
|
||||
- `String` | `ArrayBuffer` | `ArrayBufferView` | `Blob`: data to send
|
||||
- `Function`: optional, callback upon `drain`
|
||||
- `close`
|
||||
- Disconnects the client.
|
||||
|
||||
@@ -75,6 +75,7 @@ function Socket(uri, opts){
|
||||
this.upgrade = false !== opts.upgrade;
|
||||
this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
|
||||
this.forceJSONP = !!opts.forceJSONP;
|
||||
this.forceBase64 = !!opts.forceBase64;
|
||||
this.timestampParam = opts.timestampParam || 't';
|
||||
this.timestampRequests = opts.timestampRequests;
|
||||
this.flashPath = opts.flashPath || '';
|
||||
@@ -85,6 +86,8 @@ function Socket(uri, opts){
|
||||
this.policyPort = opts.policyPort || 843;
|
||||
this.rememberUpgrade = opts.rememberUpgrade || false;
|
||||
this.open();
|
||||
this.binaryType = null;
|
||||
this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
|
||||
}
|
||||
|
||||
Socket.priorWebsocketSuccess = false;
|
||||
@@ -144,10 +147,12 @@ Socket.prototype.createTransport = function (name) {
|
||||
path: this.path,
|
||||
query: query,
|
||||
forceJSONP: this.forceJSONP,
|
||||
forceBase64: this.forceBase64,
|
||||
timestampRequests: this.timestampRequests,
|
||||
timestampParam: this.timestampParam,
|
||||
flashPath: this.flashPath,
|
||||
policyPort: this.policyPort
|
||||
policyPort: this.policyPort,
|
||||
socket: this
|
||||
});
|
||||
|
||||
return transport;
|
||||
@@ -231,6 +236,10 @@ Socket.prototype.probe = function (name) {
|
||||
Socket.priorWebsocketSuccess = false;
|
||||
|
||||
transport.once('open', function () {
|
||||
if (this.onlyBinaryUpgrades) {
|
||||
var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
|
||||
failed = failed || upgradeLosesBinary;
|
||||
}
|
||||
if (failed) return;
|
||||
|
||||
debug('probe transport "%s" opened', name);
|
||||
@@ -366,6 +375,7 @@ Socket.prototype.onPacket = function (packet) {
|
||||
event.toString = function () {
|
||||
return packet.data;
|
||||
};
|
||||
|
||||
this.onmessage && this.onmessage.call(this, event);
|
||||
break;
|
||||
}
|
||||
@@ -444,7 +454,7 @@ Socket.prototype.ping = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onDrain = function() {
|
||||
Socket.prototype.onDrain = function() {
|
||||
for (var i = 0; i < this.prevBufferLen; i++) {
|
||||
if (this.callbackBuffer[i]) {
|
||||
this.callbackBuffer[i]();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -30,6 +29,7 @@ function Transport (opts) {
|
||||
this.timestampRequests = opts.timestampRequests;
|
||||
this.readyState = '';
|
||||
this.agent = opts.agent || false;
|
||||
this.socket = opts.socket;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +119,7 @@ Transport.prototype.onOpen = function () {
|
||||
*/
|
||||
|
||||
Transport.prototype.onData = function (data) {
|
||||
this.onPacket(parser.decodePacket(data));
|
||||
this.onPacket(parser.decodePacket(data, this.socket.binaryType));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,12 @@ util.inherits(FlashWS, WS);
|
||||
|
||||
FlashWS.prototype.name = 'flashsocket';
|
||||
|
||||
/*
|
||||
* FlashSockets only support binary as base64 encoded strings
|
||||
*/
|
||||
|
||||
FlashWS.prototype.supportsBinary = false;
|
||||
|
||||
/**
|
||||
* Opens the transport.
|
||||
*
|
||||
@@ -91,7 +97,7 @@ FlashWS.prototype.doOpen = function(){
|
||||
load(deps, function(){
|
||||
self.ready(function(){
|
||||
WebSocket.__addTask(function () {
|
||||
self.socket = new WebSocket(self.uri());
|
||||
self.ws = new WebSocket(self.uri());
|
||||
self.addEventListeners();
|
||||
});
|
||||
});
|
||||
@@ -105,7 +111,7 @@ FlashWS.prototype.doOpen = function(){
|
||||
*/
|
||||
|
||||
FlashWS.prototype.doClose = function(){
|
||||
if (!this.socket) return;
|
||||
if (!this.ws) return;
|
||||
var self = this;
|
||||
WebSocket.__addTask(function(){
|
||||
WS.prototype.doClose.call(self);
|
||||
|
||||
@@ -79,6 +79,12 @@ function JSONPPolling (opts) {
|
||||
|
||||
util.inherits(JSONPPolling, Polling);
|
||||
|
||||
/*
|
||||
* JSONP only supports binary as base64 encoded strings
|
||||
*/
|
||||
|
||||
JSONPPolling.prototype.supportsBinary = false;
|
||||
|
||||
/**
|
||||
* Closes the socket
|
||||
*
|
||||
|
||||
@@ -63,6 +63,12 @@ function XHR(opts){
|
||||
|
||||
util.inherits(XHR, Polling);
|
||||
|
||||
/**
|
||||
* XHR supports binary
|
||||
*/
|
||||
|
||||
XHR.prototype.supportsBinary = true;
|
||||
|
||||
/**
|
||||
* Creates a request.
|
||||
*
|
||||
@@ -75,6 +81,7 @@ XHR.prototype.request = function(opts){
|
||||
opts.uri = this.uri();
|
||||
opts.xd = this.xd;
|
||||
opts.agent = this.agent || false;
|
||||
opts.supportsBinary = this.supportsBinary;
|
||||
return new Request(opts);
|
||||
};
|
||||
|
||||
@@ -87,7 +94,8 @@ XHR.prototype.request = function(opts){
|
||||
*/
|
||||
|
||||
XHR.prototype.doWrite = function(data, fn){
|
||||
var req = this.request({ method: 'POST', data: data });
|
||||
var isBinary = typeof data !== 'string' && data !== undefined;
|
||||
var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
|
||||
var self = this;
|
||||
req.on('success', fn);
|
||||
req.on('error', function(err){
|
||||
@@ -129,7 +137,7 @@ function Request(opts){
|
||||
this.async = false !== opts.async;
|
||||
this.data = undefined != opts.data ? opts.data : null;
|
||||
this.agent = opts.agent;
|
||||
this.create();
|
||||
this.create(opts.isBinary, opts.supportsBinary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,17 +152,26 @@ Emitter(Request.prototype);
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.create = function(){
|
||||
Request.prototype.create = function(isBinary, supportsBinary){
|
||||
var xhr = this.xhr = new XMLHttpRequest({ agent: this.agent, xdomain: this.xd });
|
||||
var self = this;
|
||||
|
||||
try {
|
||||
debug('xhr open %s: %s', this.method, this.uri);
|
||||
xhr.open(this.method, this.uri, this.async);
|
||||
if (supportsBinary) {
|
||||
// This has to be done after open because Firefox is stupid
|
||||
// http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
|
||||
xhr.responseType = 'arraybuffer';
|
||||
}
|
||||
|
||||
if ('POST' == this.method) {
|
||||
try {
|
||||
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
|
||||
if (isBinary) {
|
||||
xhr.setRequestHeader('Content-type', 'application/octet-stream');
|
||||
} else {
|
||||
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
@@ -169,7 +186,16 @@ Request.prototype.create = function(){
|
||||
try {
|
||||
if (4 != xhr.readyState) return;
|
||||
if (200 == xhr.status || 1223 == xhr.status) {
|
||||
data = xhr.responseText;
|
||||
var contentType = xhr.getResponseHeader('Content-Type');
|
||||
if (contentType === 'application/octet-stream') {
|
||||
data = xhr.response;
|
||||
} else {
|
||||
if (!supportsBinary) {
|
||||
data = xhr.responseText;
|
||||
} else {
|
||||
data = 'ok';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// make sure the `error` event handler that's user-set
|
||||
// does not throw in the same tick and gets caught here
|
||||
@@ -189,7 +215,7 @@ Request.prototype.create = function(){
|
||||
debug('xhr data %s', this.data);
|
||||
xhr.send(this.data);
|
||||
} catch (e) {
|
||||
// Need to defer since .create() is called directly from the constructor
|
||||
// Need to defer since .create() is called directly fhrom the constructor
|
||||
// and thus the 'error' event can only be only bound *after* this exception
|
||||
// occurs. Therefore, also, we cannot throw here at all.
|
||||
setTimeout(function() {
|
||||
@@ -280,11 +306,13 @@ if (hasAttachEvent) {
|
||||
Request.requestsCount = 0;
|
||||
Request.requests = {};
|
||||
|
||||
global.attachEvent('onunload', function(){
|
||||
function unloadHandler() {
|
||||
for (var i in Request.requests) {
|
||||
if (Request.requests.hasOwnProperty(i)) {
|
||||
Request.requests[i].abort();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
global.attachEvent('onunload', unloadHandler);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,16 @@ module.exports = Polling;
|
||||
|
||||
var global = require('global');
|
||||
|
||||
/**
|
||||
* Is XHR2 supported?
|
||||
*/
|
||||
|
||||
var hasXHR2 = (function() {
|
||||
var XMLHttpRequest = require('xmlhttprequest');
|
||||
var xhr = new XMLHttpRequest({ agent: this.agent, xdomain: false });
|
||||
return null != xhr.responseType;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Polling interface.
|
||||
*
|
||||
@@ -27,6 +37,10 @@ var global = require('global');
|
||||
*/
|
||||
|
||||
function Polling(opts){
|
||||
var forceBase64 = (opts && opts.forceBase64);
|
||||
if (!hasXHR2 || forceBase64) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
Transport.call(this, opts);
|
||||
}
|
||||
|
||||
@@ -119,9 +133,7 @@ Polling.prototype.poll = function(){
|
||||
Polling.prototype.onData = function(data){
|
||||
var self = this;
|
||||
debug('polling got data %s', data);
|
||||
|
||||
// decode payload
|
||||
parser.decodePayload(data, function(packet, index, total) {
|
||||
var callback = function(packet, index, total) {
|
||||
// if its the first message we consider the transport open
|
||||
if ('opening' == self.readyState) {
|
||||
self.onOpen();
|
||||
@@ -135,7 +147,10 @@ Polling.prototype.onData = function(data){
|
||||
|
||||
// otherwise bypass onData and handle the message
|
||||
self.onPacket(packet);
|
||||
});
|
||||
};
|
||||
|
||||
// decode payload
|
||||
parser.decodePayload(data, this.socket.binaryType, callback);
|
||||
|
||||
// if an event did not trigger closing
|
||||
if ('closed' != this.readyState) {
|
||||
@@ -187,9 +202,14 @@ Polling.prototype.doClose = function(){
|
||||
Polling.prototype.write = function(packets){
|
||||
var self = this;
|
||||
this.writable = false;
|
||||
this.doWrite(parser.encodePayload(packets), function(){
|
||||
var callbackfn = function() {
|
||||
self.writable = true;
|
||||
self.emit('drain');
|
||||
};
|
||||
|
||||
var self = this;
|
||||
parser.encodePayload(packets, this.supportsBinary, function(data) {
|
||||
self.doWrite(data, callbackfn);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -215,6 +235,10 @@ Polling.prototype.uri = function(){
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.supportsBinary && !query.sid) {
|
||||
query.b64 = 1;
|
||||
}
|
||||
|
||||
query = util.qs(query);
|
||||
|
||||
// avoid port if default for schema
|
||||
|
||||
@@ -35,6 +35,10 @@ var global = require('global');
|
||||
*/
|
||||
|
||||
function WS(opts){
|
||||
var forceBase64 = (opts && opts.forceBase64);
|
||||
if (forceBase64) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
Transport.call(this, opts);
|
||||
}
|
||||
|
||||
@@ -52,6 +56,12 @@ util.inherits(WS, Transport);
|
||||
|
||||
WS.prototype.name = 'websocket';
|
||||
|
||||
/*
|
||||
* WebSockets support binary
|
||||
*/
|
||||
|
||||
WS.prototype.supportsBinary = true;
|
||||
|
||||
/**
|
||||
* Opens socket.
|
||||
*
|
||||
@@ -69,7 +79,13 @@ WS.prototype.doOpen = function(){
|
||||
var protocols = void(0);
|
||||
var opts = { agent: this.agent };
|
||||
|
||||
this.socket = new WebSocket(uri, protocols, opts);
|
||||
this.ws = new WebSocket(uri, protocols, opts);
|
||||
|
||||
if (this.ws.binaryType !== undefined) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
|
||||
this.ws.binaryType = 'arraybuffer';
|
||||
this.addEventListeners();
|
||||
};
|
||||
|
||||
@@ -82,16 +98,16 @@ WS.prototype.doOpen = function(){
|
||||
WS.prototype.addEventListeners = function(){
|
||||
var self = this;
|
||||
|
||||
this.socket.onopen = function(){
|
||||
this.ws.onopen = function(){
|
||||
self.onOpen();
|
||||
};
|
||||
this.socket.onclose = function(){
|
||||
this.ws.onclose = function(){
|
||||
self.onClose();
|
||||
};
|
||||
this.socket.onmessage = function(ev){
|
||||
this.ws.onmessage = function(ev){
|
||||
self.onData(ev.data);
|
||||
};
|
||||
this.socket.onerror = function(e){
|
||||
this.ws.onerror = function(e){
|
||||
self.onError('websocket error', e);
|
||||
};
|
||||
};
|
||||
@@ -126,8 +142,11 @@ WS.prototype.write = function(packets){
|
||||
// encodePacket efficient as it uses WS framing
|
||||
// no need for encodePayload
|
||||
for (var i = 0, l = packets.length; i < l; i++) {
|
||||
this.socket.send(parser.encodePacket(packets[i]));
|
||||
parser.encodePacket(packets[i], this.supportsBinary, function(data) {
|
||||
self.ws.send(data);
|
||||
});
|
||||
}
|
||||
|
||||
function ondrain() {
|
||||
self.writable = true;
|
||||
self.emit('drain');
|
||||
@@ -154,8 +173,8 @@ WS.prototype.onClose = function(){
|
||||
*/
|
||||
|
||||
WS.prototype.doClose = function(){
|
||||
if (typeof this.socket !== 'undefined') {
|
||||
this.socket.close();
|
||||
if (typeof this.ws !== 'undefined') {
|
||||
this.ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,6 +200,11 @@ WS.prototype.uri = function(){
|
||||
query[this.timestampParam] = +new Date;
|
||||
}
|
||||
|
||||
// communicate binary support capabilities
|
||||
if (!this.supportsBinary) {
|
||||
query.b64 = 1;
|
||||
}
|
||||
|
||||
query = util.qs(query);
|
||||
|
||||
// prepend ? to query
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"debug": "0.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"zuul": "1.5.2",
|
||||
"zuul": "1.5.4",
|
||||
"mocha": "1.16.2",
|
||||
"expect.js": "0.2.0",
|
||||
"istanbul": "0.2.3",
|
||||
|
||||
8
test/arraybuffer/index.js
Normal file
8
test/arraybuffer/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
var wsSupport = require('has-cors');
|
||||
|
||||
require('./polling.js');
|
||||
var uagent = navigator.userAgent;
|
||||
var isOldSimulator = ~uagent.indexOf('iPhone OS 4') || ~uagent.indexOf('iPhone OS 5');
|
||||
if (wsSupport && !isOldSimulator) {
|
||||
require ('./ws.js');
|
||||
}
|
||||
45
test/arraybuffer/polling.js
Normal file
45
test/arraybuffer/polling.js
Normal file
@@ -0,0 +1,45 @@
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../../');
|
||||
|
||||
describe('arraybuffer', function() {
|
||||
this.timeout(30000);
|
||||
|
||||
it('should be able to receive binary data when bouncing it back (polling)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket({ transports: ['polling'] });
|
||||
socket.on('open', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
if (data === 'hi') return;
|
||||
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to receive binary data when forcing base64 (polling)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket({ forceBase64: true });
|
||||
socket.on('open', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
if (typeof data === 'string') return;
|
||||
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
var ia = new Int8Array(data);
|
||||
expect(ia).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
50
test/arraybuffer/ws.js
Normal file
50
test/arraybuffer/ws.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../../');
|
||||
|
||||
describe('arraybuffer', function() {
|
||||
this.timeout(30000);
|
||||
|
||||
it('should be able to receive binary data when bouncing it back (ws)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket();
|
||||
socket.on('open', function() {
|
||||
socket.on('upgrade', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
if (typeof data === 'string') return;
|
||||
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to receive binary data when bouncing it back and forcing base64 (ws)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket({ forceBase64: true });
|
||||
socket.on('open', function() {
|
||||
socket.on('upgrade', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
if (typeof data === 'string') return;
|
||||
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
26
test/binary-fallback.js
Normal file
26
test/binary-fallback.js
Normal file
@@ -0,0 +1,26 @@
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../');
|
||||
|
||||
describe('binary fallback', function() {
|
||||
this.timeout(10000);
|
||||
|
||||
it('should be able to receive binary data when ArrayBuffer not available (polling)', function(done) {
|
||||
var socket = new eio.Socket({ forceBase64: true });
|
||||
socket.on('open', function() {
|
||||
socket.send('give binary');
|
||||
var firstPacket = true;
|
||||
socket.on('message', function (data) {
|
||||
if (firstPacket) {
|
||||
firstPacket = false;
|
||||
return;
|
||||
}
|
||||
|
||||
expect(data.base64).to.be(true);
|
||||
expect(data.data).to.equal('AAECAwQ=');
|
||||
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
8
test/blob/index.js
Normal file
8
test/blob/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
var wsSupport = require('has-cors');
|
||||
|
||||
require('./polling.js');
|
||||
var uagent = navigator.userAgent;
|
||||
var isOldSimulator = ~uagent.indexOf('iPhone OS 4') || ~uagent.indexOf('iPhone OS 5');
|
||||
if (wsSupport && !isOldSimulator) {
|
||||
require('./ws.js');
|
||||
}
|
||||
66
test/blob/polling.js
Normal file
66
test/blob/polling.js
Normal file
@@ -0,0 +1,66 @@
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../../');
|
||||
|
||||
var blobSupported = (function() {
|
||||
try {
|
||||
var b = new Blob(['hi']);
|
||||
return b.size == 2;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
describe('blob', function() {
|
||||
this.timeout(30000);
|
||||
|
||||
it('should be able to receive binary data as blob when bouncing it back (polling)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket();
|
||||
socket.binaryType = 'blob';
|
||||
socket.on('open', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
if (typeof data === 'string') return;
|
||||
|
||||
expect(data).to.be.a(Blob);
|
||||
var fr = new FileReader();
|
||||
fr.onload = function() {
|
||||
var ab = this.result;
|
||||
var ia = new Int8Array(ab);
|
||||
expect(ia).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
};
|
||||
fr.readAsArrayBuffer(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to send data as a blob when bouncing it back (polling)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket();
|
||||
socket.on('open', function() {
|
||||
if (blobSupported) {
|
||||
socket.send(new Blob([binaryData.buffer]));
|
||||
} else {
|
||||
var bb = new BlobBuilder();
|
||||
bb.append(binaryData.buffer);
|
||||
socket.send(bb.getBlob());
|
||||
}
|
||||
socket.on('message', function (data) {
|
||||
if (typeof data == 'string') { return; }
|
||||
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
91
test/blob/ws.js
Normal file
91
test/blob/ws.js
Normal file
@@ -0,0 +1,91 @@
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../../');
|
||||
|
||||
var blobSupported = (function() {
|
||||
try {
|
||||
var b = new Blob(['hi']);
|
||||
return b.size == 2;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
describe('blob', function() {
|
||||
this.timeout(30000);
|
||||
|
||||
it('should be able to receive binary data as blob when bouncing it back (ws)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket();
|
||||
socket.binaryType = 'blob';
|
||||
socket.on('open', function() {
|
||||
socket.on('upgrade', function() {
|
||||
socket.send(binaryData);
|
||||
socket.on('message', function (data) {
|
||||
expect(data).to.be.a(Blob);
|
||||
var fr = new FileReader();
|
||||
fr.onload = function() {
|
||||
var ab = this.result;
|
||||
var ia = new Int8Array(ab);
|
||||
expect(ia).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
};
|
||||
fr.readAsArrayBuffer(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to send data as a blob when bouncing it back (ws)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket();
|
||||
socket.on('open', function() {
|
||||
socket.on('upgrade', function() {
|
||||
if (blobSupported) {
|
||||
socket.send(new Blob([binaryData.buffer]));
|
||||
} else {
|
||||
var bb = new BlobBuilder();
|
||||
bb.append(binaryData.buffer);
|
||||
socket.send(bb.getBlob());
|
||||
}
|
||||
socket.on('message', function (data) {
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to send data as a blob encoded into base64 when bouncing it back (ws)', function(done) {
|
||||
var binaryData = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
binaryData[i] = i;
|
||||
}
|
||||
var socket = new eio.Socket({ forceBase64: true });
|
||||
socket.on('open', function() {
|
||||
socket.on('upgrade', function() {
|
||||
if (blobSupported) {
|
||||
socket.send(new Blob([binaryData.buffer]));
|
||||
} else {
|
||||
var bb = new BlobBuilder();
|
||||
bb.append(binaryData.buffer);
|
||||
socket.send(bb.getBlob());
|
||||
}
|
||||
socket.on('message', function (data) {
|
||||
expect(data).to.be.an(ArrayBuffer);
|
||||
expect(new Int8Array(data)).to.eql(binaryData);
|
||||
socket.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
152
test/browser-only-parser.js
Normal file
152
test/browser-only-parser.js
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
/**
|
||||
* Test dependencies.
|
||||
*/
|
||||
|
||||
var expect = require('expect.js');
|
||||
var eio = require('../');
|
||||
|
||||
var parser = eio.parser
|
||||
|
||||
/**
|
||||
* Shortcuts
|
||||
*/
|
||||
|
||||
var encode = parser.encodePacket;
|
||||
var decode = parser.decodePacket;
|
||||
var encPayload = parser.encodePayload;
|
||||
var decPayload = parser.decodePayload;
|
||||
var encPayloadB = parser.encodePayloadAsArrayBuffer;
|
||||
var encPayloadBB = parser.encodePayloadAsBlob;
|
||||
var decPayloadB = parser.decodePayloadAsBinary;
|
||||
|
||||
var canUseBlobs = (function() {
|
||||
try {
|
||||
new Blob(["hi"]);
|
||||
return true;
|
||||
} catch(e) {
|
||||
return !!global.BlobBuilder;
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Tests.
|
||||
*/
|
||||
|
||||
describe('browser-only-parser', function () {
|
||||
it('should encode a binary message', function(done) {
|
||||
var data = new Int8Array(5);
|
||||
for (var i = 0; i < data.length; i++) data[i] = i;
|
||||
encode({ type: 'message', data: data }, function (encoded) {
|
||||
expect(decode(encoded)).to.eql({ type: 'message', data: data.buffer });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode/decode mixed binary and string contents as b64', function(done) {
|
||||
var data = new Int8Array(5);
|
||||
for (var i = 0; i < data.length; i++) data[i] = i;
|
||||
encPayload([{ type: 'message', data: data }, { type: 'message', data: 'hello' }], function(encoded) {
|
||||
decPayload(encoded, function(packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet.type).to.eql('message');
|
||||
if (!isLast) {
|
||||
expect(new Int8Array(packet.data)).to.eql(data);
|
||||
} else {
|
||||
expect(packet.data).to.eql('hello');
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode binary contents as binary (ArrayBuffer)', function(done) {
|
||||
var first = new Int8Array(5);
|
||||
for (var i = 0; i < first.length; i++) first[i] = i;
|
||||
var second = new Int8Array(4);
|
||||
for (var i = 0; i < second.length; i++) second[i] = first.length + i;
|
||||
|
||||
encPayloadB([{ type: 'message', data: first }, { type: 'message', data: second }], function(data) {
|
||||
decPayloadB(data, function(packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet.type).to.eql('message');
|
||||
if (!isLast) {
|
||||
expect(new Int8Array(packet.data)).to.eql(first);
|
||||
} else {
|
||||
expect(new Int8Array(packet.data)).to.eql(second);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode mixed binary and string contents as binary (ArrayBuffer)', function(done) {
|
||||
var first = new Int8Array(15);
|
||||
for (var i = 0; i < first.length; i++) first[i] = i;
|
||||
|
||||
encPayloadB([ { type: 'message', data: first }, { type: 'message', data: 'hello' }, { type: 'close' } ], function(data) {
|
||||
decPayloadB(data, function(packet, index, total) {
|
||||
if (index == 0) {
|
||||
expect(packet.type).to.eql('message');
|
||||
expect(new Int8Array(packet.data)).to.eql(first);
|
||||
} else if (index == 1) {
|
||||
expect(packet.type).to.eql('message');
|
||||
expect(packet.data).to.eql('hello');
|
||||
} else {
|
||||
expect(packet.type).to.eql('close');
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (canUseBlobs) {
|
||||
it('should encode binary contents as binary (Blob)', function(done) {
|
||||
var first = new Int8Array(5);
|
||||
for (var i = 0; i < first.length; i++) first[i] = i;
|
||||
var second = new Int8Array(4);
|
||||
for (var i = 0; i < second.length; i++) second[i] = first.length + i;
|
||||
|
||||
encPayloadBB([{ type: 'message', data: first }, { type: 'message', data: second }], function(data) {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function() {
|
||||
decPayloadB(this.result, function(packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet.type).to.eql('message');
|
||||
if (!isLast) {
|
||||
expect(new Int8Array(packet.data)).to.eql(first);
|
||||
} else {
|
||||
expect(new Int8Array(packet.data)).to.eql(second);
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
fr.readAsArrayBuffer(data);
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode mixed binary and string contents as binary (Blob)', function(done) {
|
||||
var first = new Int8Array(5);
|
||||
for (var i = 0; i < first.length; i++) first[i] = i;
|
||||
|
||||
encPayloadBB([ { type: 'message', data: first }, { type: 'message', data: 'hello' }, { type: 'close' } ], function(data) {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function() {
|
||||
decPayloadB(this.result, function(packet, index, total) {
|
||||
if (index == 0) {
|
||||
expect(packet.type).to.eql('message');
|
||||
expect(new Int8Array(packet.data)).to.eql(first);
|
||||
} else if (index == 1) {
|
||||
expect(packet.type).to.eql('message');
|
||||
expect(packet.data).to.eql('hello');
|
||||
} else {
|
||||
expect(packet.type).to.eql('close');
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
fr.readAsArrayBuffer(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -2,7 +2,7 @@ var expect = require('expect.js');
|
||||
var eio = require('../');
|
||||
|
||||
describe('connection', function() {
|
||||
this.timeout(10000);
|
||||
this.timeout(20000);
|
||||
|
||||
it('should connect to localhost', function(done){
|
||||
var socket = new eio.Socket();
|
||||
|
||||
@@ -7,6 +7,21 @@ global.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = null;
|
||||
global.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = null;
|
||||
global.WEB_SOCKET_SWF_LOCATION = null;
|
||||
|
||||
var blobSupported = (function() {
|
||||
try {
|
||||
new Blob(['hi']);
|
||||
return true;
|
||||
} catch(e) {}
|
||||
return false;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Create a blob builder even when vendor prefixes exist
|
||||
*/
|
||||
|
||||
var BlobBuilder = global.BlobBuilder || global.WebKitBlobBuilder || global.MSBlobBuilder || global.MozBlobBuilder;
|
||||
var blobBuilderSupported = !!BlobBuilder && !!BlobBuilder.prototype.append && !!BlobBuilder.prototype.getBlob;
|
||||
|
||||
require('./engine.io-client');
|
||||
require('./util');
|
||||
require('./parser');
|
||||
@@ -16,4 +31,14 @@ require('./transport');
|
||||
// browser only tests
|
||||
if (env.browser) {
|
||||
require('./connection');
|
||||
if (global.ArrayBuffer) {
|
||||
require('./browser-only-parser');
|
||||
require('./arraybuffer');
|
||||
} else {
|
||||
require('./binary-fallback');
|
||||
}
|
||||
|
||||
if (blobSupported || blobBuilderSupported) {
|
||||
require('./blob');
|
||||
}
|
||||
}
|
||||
|
||||
233
test/parser.js
233
test/parser.js
@@ -15,7 +15,7 @@ var parser = eio.parser
|
||||
var encode = parser.encodePacket
|
||||
, decode = parser.decodePacket
|
||||
, encPayload = parser.encodePayload
|
||||
, decPayload = parser.decodePayload
|
||||
, decPayload = parser.decodePayload;
|
||||
|
||||
/**
|
||||
* Tests.
|
||||
@@ -25,59 +25,85 @@ describe('parser', function () {
|
||||
|
||||
describe('packets', function () {
|
||||
describe('basic functionality', function () {
|
||||
it('should encode packets as strings', function () {
|
||||
expect(encode({ type: 'message', data: 'test' })).to.be.a('string');
|
||||
it('should encode packets as strings', function (done) {
|
||||
encode({ type: 'message', data: 'test' }, function(data) {
|
||||
expect(data).to.be.a('string');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should decode packets as objects', function () {
|
||||
expect(decode(encode({ type: 'message', data: 'test' }))).to.be.an('object');
|
||||
it('should decode packets as objects', function (done) {
|
||||
encode({ type: 'message', data: 'test' }, function(data) {
|
||||
expect(decode(data)).to.be.an('object');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('encoding and decoding', function () {
|
||||
it('should allow no data', function () {
|
||||
expect(decode(encode({ type: 'message' })))
|
||||
.to.eql({ type: 'message' });
|
||||
it('should allow no data', function (done) {
|
||||
encode({ type: 'message' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'message' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode an open packet', function () {
|
||||
expect(decode(encode({ type: 'open', data: '{"some":"json"}' })))
|
||||
.to.eql({ type: 'open', data: '{"some":"json"}' });
|
||||
it('should encode an open packet', function (done) {
|
||||
encode({ type: 'open', data: '{"some":"json"}' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'open', data: '{"some":"json"}' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode a close packet', function () {
|
||||
expect(decode(encode({ type: 'close' })))
|
||||
.to.eql({ type: 'close' });
|
||||
it('should encode a close packet', function (done) {
|
||||
encode({ type: 'close' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'close' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode a ping packet', function () {
|
||||
expect(decode(encode({ type: 'ping', data: '1' })))
|
||||
.to.eql({ type: 'ping', data: '1' });
|
||||
it('should encode a ping packet', function (done) {
|
||||
encode({ type: 'ping', data: '1' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'ping', data: '1' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode a pong packet', function () {
|
||||
expect(decode(encode({ type: 'pong', data: '1' })))
|
||||
.to.eql({ type: 'pong', data: '1' });
|
||||
it('should encode a pong packet', function (done) {
|
||||
encode({ type: 'pong', data: '1' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'pong', data: '1' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode a message packet', function () {
|
||||
expect(decode(encode({ type: 'message', data: 'aaa' })))
|
||||
.to.eql({ type: 'message', data: 'aaa' });
|
||||
it('should encode a message packet', function (done) {
|
||||
encode({ type: 'message', data: 'aaa' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'message', data: 'aaa' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode a message packet coercing to string', function () {
|
||||
expect(decode(encode({ type: 'message', data: 1 })))
|
||||
.to.eql({ type: 'message', data: '1' });
|
||||
it('should encode a message packet coercing to string', function (done) {
|
||||
encode({ type: 'message', data: 1 }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'message', data: 1 });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode an upgrade packet', function () {
|
||||
expect(decode(encode({ type: 'upgrade' })))
|
||||
.to.eql({ type: 'upgrade' });
|
||||
it('should encode an upgrade packet', function (done) {
|
||||
encode({ type: 'upgrade' }, function(data) {
|
||||
expect(decode(data)).to.eql({ type: 'upgrade' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should match the encoding format', function () {
|
||||
expect(encode({ type: 'message', data: 'test' })).to.match(/^[0-9]/);
|
||||
expect(encode({ type: 'message' })).to.match(/^[0-9]$/);
|
||||
encode({ type: 'message', data: 'test' }, function(data) {
|
||||
expect(data).to.match(/^[0-9]/);
|
||||
});
|
||||
encode({ type: 'message' }, function(data) {
|
||||
expect(data).to.match(/^[0-9]$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,7 +112,7 @@ describe('parser', function () {
|
||||
|
||||
it('should disallow bad format', function () {
|
||||
expect(decode(':::')).to.eql(err);
|
||||
})
|
||||
});
|
||||
|
||||
it('should disallow inexistent types', function () {
|
||||
expect(decode('94103')).to.eql(err);
|
||||
@@ -94,93 +120,104 @@ describe('parser', function () {
|
||||
});
|
||||
});
|
||||
|
||||
var packets, indices, totals;
|
||||
|
||||
initCallback = function() {
|
||||
packets = []; indices = []; totals = [];
|
||||
}
|
||||
|
||||
callback = function(packet, index, total) {
|
||||
packets.push(packet);
|
||||
indices.push(index);
|
||||
totals.push(total);
|
||||
}
|
||||
|
||||
describe('payloads', function () {
|
||||
describe('basic functionality', function () {
|
||||
it('should encode payloads as strings', function () {
|
||||
expect(encPayload([{ type: 'ping' }, { type: 'post' }])).to.be.a('string');
|
||||
});
|
||||
|
||||
it('should decode payloads as arrays', function () {
|
||||
initCallback();
|
||||
decPayload(encPayload(['1:a', '2:b']), callback)
|
||||
expect(packets).to.be.an('array');
|
||||
it('should encode payloads as strings', function (done) {
|
||||
encPayload([{ type: 'ping' }, { type: 'post' }], function(data) {
|
||||
expect(data).to.be.a('string');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('encoding and decoding', function () {
|
||||
it('should encode/decode packets', function () {
|
||||
initCallback();
|
||||
decPayload(encPayload([{ type: 'message', data: 'a' }]), callback);
|
||||
expect(packets).to.eql([{ type: 'message', data: 'a' }]);
|
||||
var seen = 0;
|
||||
it('should encode/decode packets', function (done) {
|
||||
encPayload([{ type: 'message', data: 'a' }], function(data) {
|
||||
decPayload(data,
|
||||
function(packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(isLast).to.eql(true);
|
||||
seen++;
|
||||
});
|
||||
});
|
||||
encPayload([{type: 'message', data: 'a'}, {type: 'ping'}], function(data) {
|
||||
decPayload(data,
|
||||
function(packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
if (!isLast) {
|
||||
expect(packet.type).to.eql('message');
|
||||
} else {
|
||||
expect(packet.type).to.eql('ping');
|
||||
if (seen == 2) { done(); }
|
||||
}
|
||||
seen++;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should encode/decode empty payloads', function () {
|
||||
initCallback();
|
||||
decPayload(encPayload([]), callback);
|
||||
expect(packets).to.have.length(0);
|
||||
expect(indices).to.have.length(0);
|
||||
expect(totals).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should encode/decode multiple packets with correct indices/totals', function () {
|
||||
initCallback();
|
||||
decPayload(encPayload([{ type: 'message', data: 'a' },
|
||||
{ type: 'message', data: 'b' }, { type: 'message', data: 'c' }]), callback);
|
||||
expect(packets).to.eql([{ type: 'message', data: 'a' },
|
||||
{ type: 'message', data: 'b' }, { type: 'message', data: 'c' }]);
|
||||
expect(indices).to.eql([ 3, 7, 11 ]);
|
||||
expect(totals).to.eql([ 12, 12, 12 ]);
|
||||
encPayload([], function(data) {
|
||||
decPayload(data,
|
||||
function (packet, index, total) {
|
||||
expect(packet.type).to.eql('open');
|
||||
var isLast = index + 1 == total;
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('decoding error handling', function () {
|
||||
var err = [{ type: 'error', data: 'parser error' }];
|
||||
var err = { type: 'error', data: 'parser error' };
|
||||
|
||||
it('should err on bad payload format', function () {
|
||||
initCallback();
|
||||
decPayload('1!', callback)
|
||||
expect(packets).to.eql(err);
|
||||
|
||||
initCallback();
|
||||
decPayload('', callback);
|
||||
expect(packets).to.eql(err);
|
||||
|
||||
initCallback();
|
||||
decPayload('))', callback);
|
||||
expect(packets).to.eql(err);
|
||||
decPayload('1!', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
decPayload('', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
decPayload('))', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should err on bad payload length', function () {
|
||||
initCallback();
|
||||
decPayload('1:aa', callback);
|
||||
expect(packets).to.eql(err);
|
||||
|
||||
initCallback();
|
||||
decPayload('1:', callback);
|
||||
expect(packets).to.eql(err);
|
||||
|
||||
initCallback();
|
||||
decPayload('1:a2:b', callback);
|
||||
expect(packets).to.eql(err);
|
||||
// line 137
|
||||
decPayload('1:', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should err on bad packet format', function () {
|
||||
initCallback();
|
||||
decPayload('3:99:', callback);
|
||||
expect(packets).to.eql(err);
|
||||
// line 137
|
||||
decPayload('3:99:', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
// line 146
|
||||
decPayload('1:aa', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
// line 137
|
||||
decPayload('1:a2:b', function (packet, index, total) {
|
||||
var isLast = index + 1 == total;
|
||||
expect(packet).to.eql(err);
|
||||
expect(isLast).to.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -26,4 +26,18 @@ app.get('/test/support/engine.io.js', function(err, res, next) {
|
||||
|
||||
server.on('connection', function(socket){
|
||||
socket.send('hi');
|
||||
|
||||
// Bounce any received messages back
|
||||
socket.on('message', function (data) {
|
||||
if (data === 'give binary') {
|
||||
var abv = new Int8Array(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
abv[i] = i;
|
||||
}
|
||||
socket.send(abv);
|
||||
return;
|
||||
}
|
||||
|
||||
socket.send(data);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user