mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-11 16:08:24 -05:00
Compare commits
27 Commits
1.3.3
...
dynamic-na
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
213577204a | ||
|
|
dd72676c25 | ||
|
|
3bf7be73a0 | ||
|
|
0360553c99 | ||
|
|
de5cbdb833 | ||
|
|
a93d05a9f3 | ||
|
|
5ce06d3088 | ||
|
|
816bfec783 | ||
|
|
0a17c90d7a | ||
|
|
3645741b86 | ||
|
|
f2a7322b5a | ||
|
|
97c6568f65 | ||
|
|
8814825a35 | ||
|
|
58eaecad27 | ||
|
|
94157e650e | ||
|
|
0935b81da2 | ||
|
|
afa871bb8a | ||
|
|
1b01e16a6c | ||
|
|
bd6f638c8f | ||
|
|
83b36e54ac | ||
|
|
2f0d9d05af | ||
|
|
429eb0cb7c | ||
|
|
ac8e8598d7 | ||
|
|
0ce0ce1dbc | ||
|
|
cc7ce79251 | ||
|
|
1b77c27f7b | ||
|
|
1f8bb8a0ec |
46
Readme.md
46
Readme.md
@@ -240,6 +240,40 @@ server.listen(3000);
|
||||
Hash of `Socket` objects that are connected to this namespace indexed
|
||||
by `id`.
|
||||
|
||||
### Namespace#clients(fn:Function)
|
||||
|
||||
Gets a list of client IDs connected to this namespace (across all nodes if applicable).
|
||||
|
||||
An example to get all clients in a namespace:
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.of('/chat').clients(function(error, clients){
|
||||
if (error) throw error;
|
||||
console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
|
||||
});
|
||||
```
|
||||
|
||||
An example to get all clients in namespace's room:
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.of('/chat').in('general').clients(function(error, clients){
|
||||
if (error) throw error;
|
||||
console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
|
||||
});
|
||||
```
|
||||
|
||||
As with broadcasting, the default is all clients from the default namespace ('/'):
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.clients(function(error, clients){
|
||||
if (error) throw error;
|
||||
console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
|
||||
});
|
||||
```
|
||||
|
||||
### Namespace#use(fn:Function):Namespace
|
||||
|
||||
Registers a middleware, which is a function that gets executed for
|
||||
@@ -341,6 +375,18 @@ server.listen(3000);
|
||||
});
|
||||
```
|
||||
|
||||
### Socket#compress(v:Boolean):Socket
|
||||
|
||||
Sets a modifier for a subsequent event emission that the event data will
|
||||
only be _compressed_ if the value is `true`. Defaults to `true` when you don't call the method.
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){
|
||||
socket.compress(false).emit('an event', { some: 'data' });
|
||||
});
|
||||
```
|
||||
|
||||
### Client
|
||||
|
||||
The `Client` class represents an incoming transport (engine.io)
|
||||
|
||||
@@ -59,26 +59,40 @@ Client.prototype.setup = function(){
|
||||
*/
|
||||
|
||||
Client.prototype.connect = function(name){
|
||||
debug('connecting to namespace %s', name);
|
||||
if (!this.server.nsps[name]) {
|
||||
this.packet({ type: parser.ERROR, nsp: name, data : 'Invalid namespace'});
|
||||
return;
|
||||
}
|
||||
var nsp = this.server.of(name);
|
||||
if ('/' != name && !this.nsps['/']) {
|
||||
this.connectBuffer.push(name);
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var socket = nsp.add(this, function(){
|
||||
self.sockets.push(socket);
|
||||
self.nsps[nsp.name] = socket;
|
||||
debug('connecting to namespace %s', name);
|
||||
|
||||
if ('/' == nsp.name && self.connectBuffer.length > 0) {
|
||||
self.connectBuffer.forEach(self.connect, self);
|
||||
self.connectBuffer = [];
|
||||
function connectNamespace() {
|
||||
var nsp = self.server.of(name);
|
||||
if ('/' != name && !self.nsps['/']) {
|
||||
self.connectBuffer.push(name);
|
||||
return;
|
||||
}
|
||||
|
||||
var socket = nsp.add(self, function(){
|
||||
self.sockets.push(socket);
|
||||
self.nsps[nsp.name] = socket;
|
||||
|
||||
if ('/' == nsp.name && self.connectBuffer.length > 0) {
|
||||
self.connectBuffer.forEach(self.connect, self);
|
||||
self.connectBuffer = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (self.server.nsps[name]) {
|
||||
// Namespace already created, connect
|
||||
connectNamespace();
|
||||
return;
|
||||
}
|
||||
|
||||
self.server.checkNamespace(name, function(allow) {
|
||||
if (allow) {
|
||||
connectNamespace();
|
||||
return
|
||||
}
|
||||
|
||||
self.packet({ type: parser.ERROR, nsp: name, data : 'Invalid namespace'});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -135,17 +149,18 @@ Client.prototype.close = function(){
|
||||
* @param {Object} packet object
|
||||
* @param {Boolean} whether packet is already encoded
|
||||
* @param {Boolean} whether packet is volatile
|
||||
* @param {Boolean} whether packet should be compressed
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Client.prototype.packet = function(packet, preEncoded, volatile){
|
||||
Client.prototype.packet = function(packet, preEncoded, volatile, compress){
|
||||
var self = this;
|
||||
|
||||
// this writes to the actual connection
|
||||
function writeToEngine(encodedPackets) {
|
||||
if (volatile && !self.conn.transport.writable) return;
|
||||
for (var i = 0; i < encodedPackets.length; i++) {
|
||||
self.conn.write(encodedPackets[i]);
|
||||
self.conn.write(encodedPackets[i], { compress: compress });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
lib/index.js
57
lib/index.js
@@ -43,6 +43,7 @@ function Server(srv, opts){
|
||||
}
|
||||
opts = opts || {};
|
||||
this.nsps = {};
|
||||
this.nspValidators = [];
|
||||
this.path(opts.path || '/socket.io');
|
||||
this.serveClient(false !== opts.serveClient);
|
||||
this.adapter(opts.adapter || Adapter);
|
||||
@@ -69,7 +70,10 @@ Server.prototype.checkRequest = function(req, fn) {
|
||||
if (origin) {
|
||||
try {
|
||||
var parts = url.parse(origin);
|
||||
parts.port = parts.port || 80;
|
||||
var defaultPort = 'https:' == parts.protocol ? 443 : 80;
|
||||
parts.port = parts.port != null
|
||||
? parts.port
|
||||
: defaultPort;
|
||||
var ok =
|
||||
~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
|
||||
~this._origins.indexOf(parts.hostname + ':*') ||
|
||||
@@ -134,6 +138,53 @@ Server.prototype.set = function(key, val){
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up server middleware to validate incoming namespaces not already created on the server.
|
||||
*
|
||||
* @return {Server} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.useNamespaceValidator = function(fn){
|
||||
this.nspValidators.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the middleware for an incoming namespace not already created on the server.
|
||||
*
|
||||
* @param name of incomming namespace
|
||||
* @param {Function} last fn call in the middleware
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Server.prototype.checkNamespace = function(name, fn){
|
||||
var fns = this.nspValidators.slice(0);
|
||||
if (!fns.length) return fn(false);
|
||||
|
||||
var namespaceAllowed = false; // Deny unknown namespaces by default
|
||||
|
||||
function run(i){
|
||||
fns[i](name, function(err, allow){
|
||||
// upon error, short-circuit
|
||||
if (err) return fn(false);
|
||||
|
||||
// if one piece of middleware explicitly denies namespace, short-circuit
|
||||
if (allow === false) return fn(false);
|
||||
|
||||
namespaceAllowed = namespaceAllowed || allow === true;
|
||||
|
||||
// if no middleware left, summon callback
|
||||
if (!fns[i + 1]) return fn(namespaceAllowed);
|
||||
|
||||
// go on to next
|
||||
run(i + 1);
|
||||
});
|
||||
}
|
||||
|
||||
run(0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the client serving path.
|
||||
*
|
||||
@@ -251,7 +302,7 @@ Server.prototype.attachServe = function(srv){
|
||||
var self = this;
|
||||
srv.removeAllListeners('request');
|
||||
srv.on('request', function(req, res) {
|
||||
if (0 == req.url.indexOf(url)) {
|
||||
if (0 === req.url.indexOf(url)) {
|
||||
self.serve(req, res);
|
||||
} else {
|
||||
for (var i = 0; i < evs.length; i++) {
|
||||
@@ -358,7 +409,7 @@ Server.prototype.close = function(){
|
||||
* Expose main namespace (/).
|
||||
*/
|
||||
|
||||
['on', 'to', 'in', 'use', 'emit', 'send', 'write'].forEach(function(fn){
|
||||
['on', 'to', 'in', 'use', 'emit', 'send', 'write', 'clients'].forEach(function(fn){
|
||||
Server.prototype[fn] = function(){
|
||||
var nsp = this.sockets[fn];
|
||||
return nsp.apply(this.sockets, arguments);
|
||||
|
||||
@@ -7,7 +7,7 @@ var Socket = require('./socket');
|
||||
var Emitter = require('events').EventEmitter;
|
||||
var parser = require('socket.io-parser');
|
||||
var debug = require('debug')('socket.io:namespace');
|
||||
var hasBin = require('has-binary-data');
|
||||
var hasBin = require('has-binary');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
@@ -240,3 +240,15 @@ Namespace.prototype.write = function(){
|
||||
this.emit.apply(this, args);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a list of clients.
|
||||
*
|
||||
* @return {Namespace} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Namespace.prototype.clients = function(fn){
|
||||
this.adapter.clients(this.rooms, fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ var Emitter = require('events').EventEmitter;
|
||||
var parser = require('socket.io-parser');
|
||||
var url = require('url');
|
||||
var debug = require('debug')('socket.io:socket');
|
||||
var hasBin = require('has-binary-data');
|
||||
var hasBin = require('has-binary');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
@@ -202,7 +202,8 @@ Socket.prototype.write = function(){
|
||||
Socket.prototype.packet = function(packet, preEncoded){
|
||||
packet.nsp = this.nsp.name;
|
||||
var volatile = this.flags && this.flags.volatile;
|
||||
this.client.packet(packet, preEncoded, volatile);
|
||||
var compress = !this.flags || false !== this.flags.compress;
|
||||
this.client.packet(packet, preEncoded, volatile, compress);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -390,7 +391,12 @@ Socket.prototype.ondisconnect = function(){
|
||||
*/
|
||||
|
||||
Socket.prototype.onerror = function(err){
|
||||
this.emit('error', err);
|
||||
if (this.listeners('error').length) {
|
||||
this.emit('error', err);
|
||||
} else {
|
||||
console.error('Missing error handler on `socket`.');
|
||||
console.error(err.stack);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -442,3 +448,17 @@ Socket.prototype.disconnect = function(close){
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the compress flag.
|
||||
*
|
||||
* @param {Boolean} if `true`, compresses the sending data
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.compress = function(compress){
|
||||
this.flags = this.flags || {};
|
||||
this.flags.compress = compress;
|
||||
return this;
|
||||
};
|
||||
|
||||
10
package.json
10
package.json
@@ -19,11 +19,11 @@
|
||||
"test": "mocha --reporter dot --slow 200ms --bail"
|
||||
},
|
||||
"dependencies": {
|
||||
"engine.io": "1.5.1",
|
||||
"socket.io-parser": "2.2.2",
|
||||
"socket.io-client": "1.3.2",
|
||||
"socket.io-adapter": "0.3.1",
|
||||
"has-binary-data": "0.1.3",
|
||||
"engine.io": "automattic/engine.io#ddc64a",
|
||||
"socket.io-parser": "2.2.3",
|
||||
"socket.io-client": "automattic/socket.io-client#210d65",
|
||||
"socket.io-adapter": "automattic/socket.io-adapter#ae79d8",
|
||||
"has-binary": "0.1.6",
|
||||
"debug": "2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -317,6 +317,17 @@ describe('socket.io', function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should default to port 443 when protocol is https', function(done) {
|
||||
var sockets = io({ origins: 'https://foo.example:443' }).listen('54036');
|
||||
request.get('http://localhost:54036/socket.io/default/')
|
||||
.set('origin', 'https://foo.example')
|
||||
.query({ transport: 'polling' })
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('close', function(){
|
||||
@@ -586,6 +597,211 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not reuse same-namespace connections', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var connections = 0;
|
||||
|
||||
srv.listen(function() {
|
||||
var clientSocket1 = client(srv);
|
||||
var clientSocket2 = client(srv);
|
||||
sio.on('connection', function() {
|
||||
connections++;
|
||||
if(connections === 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should find all clients in a namespace', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var chatSids = [];
|
||||
var otherSid = null;
|
||||
srv.listen(function(){
|
||||
var c1 = client(srv, '/chat');
|
||||
var c2 = client(srv, '/chat', {forceNew: true});
|
||||
var c3 = client(srv, '/other', {forceNew: true});
|
||||
var total = 3;
|
||||
sio.of('/chat').on('connection', function(socket){
|
||||
chatSids.push(socket.id);
|
||||
--total || getClients();
|
||||
});
|
||||
sio.of('/other').on('connection', function(socket){
|
||||
otherSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
});
|
||||
function getClients() {
|
||||
sio.of('/chat').clients(function(error, sids) {
|
||||
expect(error).to.be.undefined;
|
||||
expect(sids).to.contain(chatSids[0]);
|
||||
expect(sids).to.contain(chatSids[1]);
|
||||
expect(sids).to.not.contain(otherSid);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('should find all clients in a namespace room', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var chatFooSid = null;
|
||||
var chatBarSid = null;
|
||||
var otherSid = null;
|
||||
srv.listen(function(){
|
||||
var c1 = client(srv, '/chat');
|
||||
var c2 = client(srv, '/chat', {forceNew: true});
|
||||
var c3 = client(srv, '/other', {forceNew: true});
|
||||
var chatIndex = 0;
|
||||
var total = 3;
|
||||
sio.of('/chat').on('connection', function(socket){
|
||||
if (chatIndex++) {
|
||||
socket.join('foo', function() {
|
||||
chatFooSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
} else {
|
||||
socket.join('bar', function() {
|
||||
chatBarSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
}
|
||||
});
|
||||
sio.of('/other').on('connection', function(socket){
|
||||
socket.join('foo', function() {
|
||||
otherSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
});
|
||||
});
|
||||
function getClients() {
|
||||
sio.of('/chat').in('foo').clients(function(error, sids) {
|
||||
expect(error).to.be.undefined;
|
||||
expect(sids).to.contain(chatFooSid);
|
||||
expect(sids).to.not.contain(chatBarSid);
|
||||
expect(sids).to.not.contain(otherSid);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('should find all clients across namespace rooms', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var chatFooSid = null;
|
||||
var chatBarSid = null;
|
||||
var otherSid = null;
|
||||
srv.listen(function(){
|
||||
var c1 = client(srv, '/chat');
|
||||
var c2 = client(srv, '/chat', {forceNew: true});
|
||||
var c3 = client(srv, '/other', {forceNew: true});
|
||||
var chatIndex = 0;
|
||||
var total = 3;
|
||||
sio.of('/chat').on('connection', function(socket){
|
||||
if (chatIndex++) {
|
||||
socket.join('foo', function() {
|
||||
chatFooSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
} else {
|
||||
socket.join('bar', function() {
|
||||
chatBarSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
}
|
||||
});
|
||||
sio.of('/other').on('connection', function(socket){
|
||||
socket.join('foo', function() {
|
||||
otherSid = socket.id;
|
||||
--total || getClients();
|
||||
});
|
||||
});
|
||||
});
|
||||
function getClients() {
|
||||
sio.of('/chat').clients(function(error, sids) {
|
||||
expect(error).to.be.undefined;
|
||||
expect(sids).to.contain(chatFooSid);
|
||||
expect(sids).to.contain(chatBarSid);
|
||||
expect(sids).to.not.contain(otherSid);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow connections to dynamic namespaces', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var namespace = '/dynamic';
|
||||
var dynamic = client(srv,namespace);
|
||||
sio.useNamespaceValidator(function(nsp, next) {
|
||||
expect(nsp).to.be(namespace);
|
||||
next(null, true);
|
||||
});
|
||||
dynamic.on('error', function(err) {
|
||||
expect().fail();
|
||||
});
|
||||
dynamic.on('connect', function() {
|
||||
expect(sio.nsps[namespace]).to.be.a(Namespace);
|
||||
expect(sio.nsps[namespace].sockets.length).to.be(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow connections to dynamic namespaces if not supported', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var namespace = '/dynamic';
|
||||
sio.useNamespaceValidator(function(nsp, next) {
|
||||
expect(nsp).to.be(namespace);
|
||||
next(null, false);
|
||||
});
|
||||
sio.on('connect', function(socket) {
|
||||
if (socket.nsp.name === namespace) {
|
||||
expect().fail();
|
||||
}
|
||||
});
|
||||
|
||||
var dynamic = client(srv,namespace);
|
||||
dynamic.on('connect', function(){
|
||||
expect().fail();
|
||||
});
|
||||
dynamic.on('error', function(err) {
|
||||
expect(err).to.be("Invalid namespace");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should not allow connections to dynamic namespaces if there is an error', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var namespace = '/dynamic';
|
||||
sio.useNamespaceValidator(function(nsp, next) {
|
||||
expect(nsp).to.be(namespace);
|
||||
next(new Error(), true);
|
||||
});
|
||||
sio.on('connect', function(socket) {
|
||||
if (socket.nsp.name === namespace) {
|
||||
expect().fail();
|
||||
}
|
||||
});
|
||||
|
||||
var dynamic = client(srv,namespace);
|
||||
dynamic.on('connect', function(){
|
||||
expect().fail();
|
||||
});
|
||||
dynamic.on('error', function(err) {
|
||||
expect(err).to.be("Invalid namespace");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('socket', function(){
|
||||
@@ -1279,6 +1495,8 @@ describe('socket.io', function(){
|
||||
});
|
||||
|
||||
it('should handle very large binary data', function(done){
|
||||
this.timeout(10000);
|
||||
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var received = 0;
|
||||
@@ -1329,6 +1547,70 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should enable compression by default', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.conn.once('packetCreate', function(packet) {
|
||||
expect(packet.options.compress).to.be(true);
|
||||
done();
|
||||
});
|
||||
s.emit('woot', 'hi');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should disable compression', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.conn.once('packetCreate', function(packet) {
|
||||
expect(packet.options.compress).to.be(false);
|
||||
done();
|
||||
});
|
||||
s.compress(false).emit('woot', 'hi');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should error with raw binary and warn', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.conn.on('upgrade', function(){
|
||||
console.log('\033[96mNote: warning expected and normal in test.\033[39m');
|
||||
socket.io.engine.write('5woooot');
|
||||
setTimeout(function(){
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not crash with raw binary', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.once('error', function(err){
|
||||
expect(err.message).to.match(/Illegal attachments/);
|
||||
done();
|
||||
});
|
||||
s.conn.on('upgrade', function(){
|
||||
socket.io.engine.write('5woooot');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('messaging many', function(){
|
||||
@@ -1651,7 +1933,6 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('middleware', function(done){
|
||||
|
||||
Reference in New Issue
Block a user