mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-11 16:08:24 -05:00
Compare commits
125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24d06d76dd | ||
|
|
4e4bbf918e | ||
|
|
b49f5c82f2 | ||
|
|
5bd67195de | ||
|
|
73fe547956 | ||
|
|
973e6cc982 | ||
|
|
4a0091b25a | ||
|
|
a1bf85b57f | ||
|
|
62ad812ee5 | ||
|
|
9ae8ed6929 | ||
|
|
4a11c16cc2 | ||
|
|
b88a758857 | ||
|
|
3352d1d726 | ||
|
|
e68557fab6 | ||
|
|
136fe960b7 | ||
|
|
da358084f0 | ||
|
|
1b4f6a5324 | ||
|
|
99346eddc5 | ||
|
|
051ffa0440 | ||
|
|
fa4fa3365a | ||
|
|
bafa184c6b | ||
|
|
e3149d5833 | ||
|
|
ae9d5277a9 | ||
|
|
2e440722a6 | ||
|
|
3fe6d4e8ec | ||
|
|
3b93c1c562 | ||
|
|
e89f82a9b0 | ||
|
|
1b90ae2587 | ||
|
|
9658e32e7a | ||
|
|
99d76664aa | ||
|
|
23eefa527a | ||
|
|
b49b35b26f | ||
|
|
16483375a7 | ||
|
|
ec305bd8df | ||
|
|
af07a1c649 | ||
|
|
5863903d44 | ||
|
|
f56d4acce6 | ||
|
|
8ea37b7351 | ||
|
|
b3cb18d910 | ||
|
|
0e41561d56 | ||
|
|
83709e9487 | ||
|
|
6f4051aaa7 | ||
|
|
87bf6910b5 | ||
|
|
8946b4ed4c | ||
|
|
a40068b5f3 | ||
|
|
9e29ec9b2b | ||
|
|
624e7cb14f | ||
|
|
b4954d767a | ||
|
|
f6eb53f5e1 | ||
|
|
9c80317574 | ||
|
|
d163d891ef | ||
|
|
54726105cb | ||
|
|
3d9e52cf93 | ||
|
|
ad74f2ff88 | ||
|
|
cf1c1273b3 | ||
|
|
1f43c4abb5 | ||
|
|
d6e6e8a2f8 | ||
|
|
fbd36b613d | ||
|
|
480b1a05bd | ||
|
|
ef729b72b4 | ||
|
|
63e197083b | ||
|
|
968e94e42b | ||
|
|
c18ed5fd4d | ||
|
|
1f7da938bd | ||
|
|
4b89bce182 | ||
|
|
8c19eef07a | ||
|
|
662b30669b | ||
|
|
001373ee17 | ||
|
|
246f3bb5c3 | ||
|
|
68d06ec94c | ||
|
|
a1feca1bd3 | ||
|
|
968105a239 | ||
|
|
2e8e26613a | ||
|
|
fbdb94d146 | ||
|
|
55572122f3 | ||
|
|
a1170a3aa6 | ||
|
|
0954301d7e | ||
|
|
328a9df8eb | ||
|
|
d99e30fca7 | ||
|
|
561dd6fd79 | ||
|
|
e9e2a91cea | ||
|
|
8a3a111a7f | ||
|
|
bd87e4dc35 | ||
|
|
71c253e992 | ||
|
|
a5cf4f57a0 | ||
|
|
a079cbc7f9 | ||
|
|
14a9fdb64f | ||
|
|
55fb100fc0 | ||
|
|
6159df3937 | ||
|
|
6f7bab5dfd | ||
|
|
7d2b44e176 | ||
|
|
0b5fdf995a | ||
|
|
a66bea5b33 | ||
|
|
a1a88aaaaf | ||
|
|
3f817c3a18 | ||
|
|
99bbd74d14 | ||
|
|
398511ddee | ||
|
|
fdf7937815 | ||
|
|
475909e642 | ||
|
|
95acec8b94 | ||
|
|
5812ddf2b0 | ||
|
|
1bbc3951bd | ||
|
|
039eed2c2a | ||
|
|
6de022b180 | ||
|
|
a06331d29f | ||
|
|
e639685370 | ||
|
|
1f2e681ce2 | ||
|
|
397944fcbe | ||
|
|
27dada65b9 | ||
|
|
99f1ac9aae | ||
|
|
ee8d0fbae0 | ||
|
|
8e08a6d419 | ||
|
|
318ae87f50 | ||
|
|
2c1b61148d | ||
|
|
507054c0a8 | ||
|
|
dfceb006d7 | ||
|
|
4d83456f74 | ||
|
|
201aad83b1 | ||
|
|
72eb61d01f | ||
|
|
163a2a696e | ||
|
|
199a479ebc | ||
|
|
d383ff9662 | ||
|
|
416b550189 | ||
|
|
536b338a01 | ||
|
|
a06ae10895 |
@@ -1,3 +1,4 @@
|
||||
support
|
||||
test
|
||||
examples
|
||||
.gitignore
|
||||
|
||||
@@ -4,6 +4,9 @@ node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
|
||||
79
History.md
79
History.md
@@ -1,4 +1,83 @@
|
||||
|
||||
1.2.1 / 2014-11-21
|
||||
==================
|
||||
|
||||
* fix protocol violations and improve error handling (GH-1880)
|
||||
* package: bump `engine.io` for websocket leak fix [3rd-Eden]
|
||||
* style tweaks
|
||||
|
||||
1.2.0 / 2014-10-27
|
||||
==================
|
||||
|
||||
* package: bump `engine.io`
|
||||
* downloads badge
|
||||
* add test to check that empty rooms are autopruned
|
||||
* added Server#origins(v:Function) description for dynamic CORS
|
||||
* added test coverage for Server#origins(function) for dynamic CORS
|
||||
* added optional Server#origins(function) for dynamic CORS
|
||||
* fix usage example for Server#close
|
||||
* package: fix main file for example application 'chat'
|
||||
* package: bump `socket.io-parser`
|
||||
* update README http ctor to createServer()
|
||||
* bump adapter with a lot of fixes for room bookkeeping
|
||||
|
||||
1.1.0 / 2014-09-04
|
||||
==================
|
||||
|
||||
* examples: minor fix of escaping
|
||||
* testing for equivalence of namespaces starting with / or without
|
||||
* update index.js
|
||||
* added relevant tests
|
||||
* take "" and "/" as equivalent namespaces on server
|
||||
* use svg instead of png to get better image quality in readme
|
||||
* make CI build faster
|
||||
* fix splice arguments and `socket.rooms` value update in `socket.leaveAll`.
|
||||
* client cannot connect to non-existing namespaces
|
||||
* bump engine.io version to get the cached IP address
|
||||
* fixed handshake object address property and made the test case more strict.
|
||||
* package: bump `engine.io`
|
||||
* fixed the failing test where server crashes on disconnect involving connectBuffer
|
||||
* npmignore: ignore `.gitignore` (fixes #1607)
|
||||
* test: added failing case for `socket.disconnect` and nsps
|
||||
* fix repo in package.json
|
||||
* improve Close documentation
|
||||
* use ephemeral ports
|
||||
* fix: We should use the standard http protocol to handler the etag header.
|
||||
* override default browser font-family for inputs
|
||||
* update has-binary-data to 1.0.3
|
||||
* add close specs
|
||||
* add ability to stop the http server even if not created inside socket.io
|
||||
* make sure server gets close
|
||||
* Add test case for checking that reconnect_failed is fired only once upon failure
|
||||
* package: bump `socket.io-parser` for `component-emitter` dep fix
|
||||
|
||||
1.0.6 / 2014-06-19
|
||||
==================
|
||||
|
||||
* package: bump `socket.io-client`
|
||||
|
||||
1.0.5 / 2014-06-16
|
||||
==================
|
||||
|
||||
* package: bump `engine.io` to fix jsonp `\n` bug and CORS warnings
|
||||
* index: fix typo [yanatan16]
|
||||
* add `removeListener` to blacklisted events
|
||||
* examples: clearer instructions to install chat example
|
||||
* index: fix namespace `connectBuffer` issue
|
||||
|
||||
1.0.4 / 2014-06-02
|
||||
==================
|
||||
|
||||
* package: bump socket.io-client
|
||||
|
||||
1.0.3 / 2014-05-31
|
||||
==================
|
||||
|
||||
* package: bump `socket.io-client`
|
||||
* package: bump `socket.io-parser` for binary ACK fix
|
||||
* package: bump `engine.io` for binary UTF8 fix
|
||||
* example: fix XSS in chat example
|
||||
|
||||
1.0.2 / 2014-05-28
|
||||
==================
|
||||
|
||||
|
||||
53
Readme.md
53
Readme.md
@@ -1,11 +1,9 @@
|
||||
### This Readme corresponds to the upcoming 1.0 release. Please refer to http://socket.io for the current 0.9.x documentation.
|
||||
|
||||
<hr />
|
||||
|
||||
# socket.io
|
||||
|
||||
[](http://travis-ci.org/automattic/socket.io)
|
||||
[](http://badge.fury.io/js/socket.io)
|
||||
[](http://travis-ci.org/Automattic/socket.io)
|
||||
[](http://badge.fury.io/js/socket.io)
|
||||

|
||||
|
||||
## How to use
|
||||
|
||||
@@ -13,7 +11,7 @@ The following example attaches socket.io to a plain Node.JS
|
||||
HTTP server listening on port `3000`.
|
||||
|
||||
```js
|
||||
var server = require('http').Server();
|
||||
var server = require('http').createServer();
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(socket){
|
||||
socket.on('event', function(data){});
|
||||
@@ -39,7 +37,7 @@ function.
|
||||
|
||||
```js
|
||||
var app = require('express')();
|
||||
var server = require('http').Server(app);
|
||||
var server = require('http').createServer(app);
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(){ /* … */ });
|
||||
server.listen(3000);
|
||||
@@ -52,7 +50,7 @@ handler function, but only by calling the `callback` method.
|
||||
|
||||
```js
|
||||
var app = require('koa')();
|
||||
var server = require('http').Server(app.callback());
|
||||
var server = require('http').createServer(app.callback());
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(){ /* … */ });
|
||||
server.listen(3000);
|
||||
@@ -129,7 +127,7 @@ server.listen(3000);
|
||||
|
||||
Sets the adapter `v`. Defaults to an instance of the `Adapter` that
|
||||
ships with socket.io which is memory based. See
|
||||
[socket.io-adapter](https://github.com/learnboost/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
If no arguments are supplied this method returns the current value.
|
||||
|
||||
@@ -139,6 +137,15 @@ server.listen(3000);
|
||||
|
||||
If no arguments are supplied this method returns the current value.
|
||||
|
||||
### Server#origins(v:Function):Server
|
||||
|
||||
Sets the allowed origins as dynamic function. Function takes two arguments `origin:String` and `callback(error, success)`, where `success` is a boolean value indicating whether origin is allowed or not.
|
||||
|
||||
__Potential drawbacks__:
|
||||
* in some situations, when it is not possible to determine `origin` it may have value of `*`
|
||||
* As this function will be executed for every request, it is advised to make this function work as fast as possible
|
||||
* If `socket.io` is used together with `Express`, the CORS headers will be affected only for `socket.io` requests. For Express can use [cors](https://github.com/troygoode/node-cors/)
|
||||
|
||||
|
||||
### Server#sockets:Namespace
|
||||
|
||||
@@ -160,7 +167,7 @@ server.listen(3000);
|
||||
|
||||
### Server#bind(srv:engine#Server):Server
|
||||
|
||||
Advanced use only. Binds the server to a specific engine.io `Server`
|
||||
Advanced use only. Binds the server to a specific engine.io `Server`
|
||||
(or compatible API) instance.
|
||||
|
||||
### Server#onconnection(socket:engine#Socket):Server
|
||||
@@ -170,14 +177,14 @@ server.listen(3000);
|
||||
|
||||
### Server#of(nsp:String):Namespace
|
||||
|
||||
Initializes and retrieves the given `Namespace` by its pathname
|
||||
Initializes and retrieves the given `Namespace` by its pathname
|
||||
identifier `nsp`.
|
||||
|
||||
If the namespace was already initialized it returns it right away.
|
||||
|
||||
### Server#emit
|
||||
|
||||
Emits an event to all connected clients. The following two are
|
||||
Emits an event to all connected clients. The following two are
|
||||
equivalent:
|
||||
|
||||
```js
|
||||
@@ -188,6 +195,24 @@ server.listen(3000);
|
||||
|
||||
For other available methods, see `Namespace` below.
|
||||
|
||||
### Server#close
|
||||
|
||||
Closes socket server
|
||||
|
||||
```js
|
||||
var Server = require('socket.io');
|
||||
var PORT = 3030;
|
||||
var server = require('http').Server();
|
||||
|
||||
var io = Server(PORT);
|
||||
|
||||
io.close(); // Close current server
|
||||
|
||||
server.listen(PORT); // PORT is free to use
|
||||
|
||||
io = Server(server);
|
||||
```
|
||||
|
||||
### Server#use
|
||||
|
||||
See `Namespace#use` below.
|
||||
@@ -288,7 +313,7 @@ server.listen(3000);
|
||||
|
||||
The mechanics of joining rooms are handled by the `Adapter`
|
||||
that has been configured (see `Server#adapter` above), defaulting to
|
||||
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
### Socket#leave(name:String[, fn:Function]):Socket
|
||||
|
||||
@@ -299,7 +324,7 @@ server.listen(3000);
|
||||
|
||||
The mechanics of leaving rooms are handled by the `Adapter`
|
||||
that has been configured (see `Server#adapter` above), defaulting to
|
||||
[socket.io-adapter](https://github.com/socket.io/socket.io-adapter).
|
||||
[socket.io-adapter](https://github.com/Automattic/socket.io-adapter).
|
||||
|
||||
### Socket#to(room:String):Socket
|
||||
### Socket#in(room:String):Socket
|
||||
|
||||
@@ -6,17 +6,20 @@ A simple chat demo for socket.io
|
||||
## How to use
|
||||
|
||||
```
|
||||
$ cd socket.io
|
||||
$ npm install
|
||||
$ cd examples/chat
|
||||
$ npm install
|
||||
$ node .
|
||||
```
|
||||
|
||||
And point your browser to `http://localhost:3000`. Optionally specify
|
||||
And point your browser to `http://localhost:3000`. Optionally, specify
|
||||
a port by supplying the `PORT` env variable.
|
||||
|
||||
## Features
|
||||
|
||||
- Multiple users can join a chat room by entering a unique username
|
||||
- Multiple users can join a chat room by each entering a unique username
|
||||
on website load.
|
||||
- Users can type chat messages to the chat room
|
||||
- Users can type chat messages to the chat room.
|
||||
- A notification is sent to all users when a user joins or leaves
|
||||
the chatroom
|
||||
the chatroom.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "socket.io-chat",
|
||||
"version": "0.0.0",
|
||||
"description": "A simple chat client using socket.io",
|
||||
"main": "app.js",
|
||||
"main": "index.js",
|
||||
"author": "Grant Timmerman",
|
||||
"private": true,
|
||||
"license": "BSD",
|
||||
|
||||
@@ -30,7 +30,7 @@ $(function() {
|
||||
if (data.numUsers === 1) {
|
||||
message += "there's 1 participant";
|
||||
} else {
|
||||
message += "there're " + data.numUsers + " participants";
|
||||
message += "there are " + data.numUsers + " participants";
|
||||
}
|
||||
log(message);
|
||||
}
|
||||
@@ -70,8 +70,8 @@ $(function() {
|
||||
|
||||
// Log a message
|
||||
function log (message, options) {
|
||||
var el = '<li class="log">' + message + '</li>';
|
||||
addMessageElement(el, options);
|
||||
var $el = $('<li>').addClass('log').text(message);
|
||||
addMessageElement($el, options);
|
||||
}
|
||||
|
||||
// Adds the visual chat message to the message list
|
||||
@@ -84,16 +84,17 @@ $(function() {
|
||||
$typingMessages.remove();
|
||||
}
|
||||
|
||||
var colorStyle = 'style="color:' + getUsernameColor(data.username) + '"';
|
||||
var usernameDiv = '<span class="username"' + colorStyle + '>' +
|
||||
data.username + '</span>';
|
||||
var messageBodyDiv = '<span class="messageBody">' +
|
||||
data.message + '</span>';
|
||||
var $usernameDiv = $('<span class="username"/>')
|
||||
.text(data.username)
|
||||
.css('color', getUsernameColor(data.username));
|
||||
var $messageBodyDiv = $('<span class="messageBody">')
|
||||
.text(data.message);
|
||||
|
||||
var typingClass = data.typing ? 'typing' : '';
|
||||
var messageDiv = '<li class="message ' + typingClass + '">' +
|
||||
usernameDiv + messageBodyDiv + '</li>';
|
||||
var $messageDiv = $(messageDiv).data('username', data.username);
|
||||
var $messageDiv = $('<li class="message"/>')
|
||||
.data('username', data.username)
|
||||
.addClass(typingClass)
|
||||
.append($usernameDiv, $messageBodyDiv);
|
||||
|
||||
addMessageElement($messageDiv, options);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ $(function() {
|
||||
|
||||
// Prevents input from having injected markup
|
||||
function cleanInput (input) {
|
||||
return $('<div/>').text(input).html() || input;
|
||||
return $('<div/>').text(input).text();
|
||||
}
|
||||
|
||||
// Updates the typing event
|
||||
@@ -228,7 +229,7 @@ $(function() {
|
||||
socket.on('login', function (data) {
|
||||
connected = true;
|
||||
// Display the welcome message
|
||||
var message = "Welcome to Socket.IO Chat — ";
|
||||
var message = "Welcome to Socket.IO Chat – ";
|
||||
log(message, {
|
||||
prepend: true
|
||||
});
|
||||
@@ -262,4 +263,4 @@ $(function() {
|
||||
socket.on('stop typing', function (data) {
|
||||
removeChatTyping(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
}
|
||||
|
||||
html {
|
||||
font-weight: 300;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
html, input {
|
||||
font-family:
|
||||
"HelveticaNeue-Light",
|
||||
"Helvetica Neue Light",
|
||||
@@ -13,8 +18,6 @@ html {
|
||||
Arial,
|
||||
"Lucida Grande",
|
||||
sans-serif;
|
||||
font-weight: 300;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
html, body {
|
||||
@@ -25,6 +28,7 @@ html, body {
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Pages */
|
||||
@@ -143,4 +147,4 @@ ul {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,12 @@ function Client(server, conn){
|
||||
Client.prototype.setup = function(){
|
||||
this.onclose = this.onclose.bind(this);
|
||||
this.ondata = this.ondata.bind(this);
|
||||
this.onerror = this.onerror.bind(this);
|
||||
this.ondecoded = this.ondecoded.bind(this);
|
||||
|
||||
this.decoder.on('decoded', this.ondecoded);
|
||||
this.conn.on('data', this.ondata);
|
||||
this.conn.on('error', this.onerror);
|
||||
this.conn.on('close', this.onclose);
|
||||
};
|
||||
|
||||
@@ -57,6 +60,10 @@ 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);
|
||||
@@ -68,9 +75,9 @@ Client.prototype.connect = function(name){
|
||||
self.sockets.push(socket);
|
||||
self.nsps[nsp.name] = socket;
|
||||
|
||||
if ('/' == nsp.name) {
|
||||
if ('/' == nsp.name && self.connectBuffer.length > 0) {
|
||||
self.connectBuffer.forEach(self.connect, self);
|
||||
delete self.connectBuffer;
|
||||
self.connectBuffer = [];
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -163,7 +170,12 @@ Client.prototype.packet = function(packet, preEncoded, volatile){
|
||||
*/
|
||||
|
||||
Client.prototype.ondata = function(data){
|
||||
this.decoder.add(data);
|
||||
// try/catch is needed for protocol violations (GH-1880)
|
||||
try {
|
||||
this.decoder.add(data);
|
||||
} catch(e) {
|
||||
this.onerror(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -185,6 +197,20 @@ Client.prototype.ondecoded = function(packet) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles an error.
|
||||
*
|
||||
* @param {Objcet} error object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Client.prototype.onerror = function(err){
|
||||
this.sockets.forEach(function(socket){
|
||||
socket.onerror(err);
|
||||
});
|
||||
this.onclose('client error');
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon transport close.
|
||||
*
|
||||
@@ -199,9 +225,10 @@ Client.prototype.onclose = function(reason){
|
||||
this.destroy();
|
||||
|
||||
// `nsps` and `sockets` are cleaned up seamlessly
|
||||
this.sockets.forEach(function(socket){
|
||||
var socket;
|
||||
while (socket = this.sockets.shift()) {
|
||||
socket.onclose(reason);
|
||||
});
|
||||
}
|
||||
|
||||
this.decoder.destroy(); // clean up decoder
|
||||
};
|
||||
@@ -214,6 +241,7 @@ Client.prototype.onclose = function(reason){
|
||||
|
||||
Client.prototype.destroy = function(){
|
||||
this.conn.removeListener('data', this.ondata);
|
||||
this.conn.removeListener('error', this.onerror);
|
||||
this.conn.removeListener('close', this.onclose);
|
||||
this.decoder.removeListener('decoded', this.ondecoded);
|
||||
};
|
||||
|
||||
36
lib/index.js
36
lib/index.js
@@ -64,6 +64,7 @@ Server.prototype.checkRequest = function(req, fn) {
|
||||
// file:// URLs produce a null Origin which can't be authorized via echo-back
|
||||
if ('null' == origin) origin = '*';
|
||||
|
||||
if (!!origin && typeof(this._origins) == 'function') return this._origins(origin, fn);
|
||||
if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
|
||||
if (origin) {
|
||||
try {
|
||||
@@ -159,7 +160,9 @@ Server.prototype.adapter = function(v){
|
||||
if (!arguments.length) return this._adapter;
|
||||
this._adapter = v;
|
||||
for (var i in this.nsps) {
|
||||
this.nsps[i].initAdapter();
|
||||
if (this.nsps.hasOwnProperty(i)) {
|
||||
this.nsps[i].initAdapter();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
@@ -209,11 +212,12 @@ Server.prototype.attach = function(srv, opts){
|
||||
res.end();
|
||||
});
|
||||
srv.listen(port);
|
||||
|
||||
}
|
||||
|
||||
// set engine.io path to `/socket.io`
|
||||
opts = opts || {};
|
||||
opts.path = opts.path || '/socket.io';
|
||||
opts.path = opts.path || this.path();
|
||||
// set origins verification
|
||||
opts.allowRequest = this.checkRequest.bind(this);
|
||||
|
||||
@@ -224,6 +228,9 @@ Server.prototype.attach = function(srv, opts){
|
||||
// attach static file serving
|
||||
if (this._serveClient) this.attachServe(srv);
|
||||
|
||||
// Export http server
|
||||
this.httpServer = srv;
|
||||
|
||||
// bind to engine events
|
||||
this.bind(this.eio);
|
||||
|
||||
@@ -263,8 +270,9 @@ Server.prototype.attachServe = function(srv){
|
||||
*/
|
||||
|
||||
Server.prototype.serve = function(req, res){
|
||||
if (req.headers.etag) {
|
||||
if (clientVersion == req.headers.etag) {
|
||||
var etag = req.headers['if-none-match'];
|
||||
if (etag) {
|
||||
if (clientVersion == etag) {
|
||||
debug('serve client 304');
|
||||
res.writeHead(304);
|
||||
res.end();
|
||||
@@ -317,6 +325,8 @@ Server.prototype.onconnection = function(conn){
|
||||
*/
|
||||
|
||||
Server.prototype.of = function(name, fn){
|
||||
if (String(name)[0] !== '/') name = '/' + name;
|
||||
|
||||
if (!this.nsps[name]) {
|
||||
debug('initializing namespace %s', name);
|
||||
var nsp = new Namespace(this, name);
|
||||
@@ -326,6 +336,24 @@ Server.prototype.of = function(name, fn){
|
||||
return this.nsps[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes server connection
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.close = function(){
|
||||
this.nsps['/'].sockets.forEach(function(socket){
|
||||
socket.onclose();
|
||||
});
|
||||
|
||||
this.engine.close();
|
||||
|
||||
if(this.httpServer){
|
||||
this.httpServer.close();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose main namespace (/).
|
||||
*/
|
||||
|
||||
@@ -25,7 +25,8 @@ exports.events = [
|
||||
'error',
|
||||
'connect',
|
||||
'disconnect',
|
||||
'newListener'
|
||||
'newListener',
|
||||
'removeListener'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -107,7 +108,7 @@ Socket.prototype.buildHandshake = function(){
|
||||
return {
|
||||
headers: this.request.headers,
|
||||
time: (new Date) + '',
|
||||
address: this.request.connection.address(),
|
||||
address: this.conn.remoteAddress,
|
||||
xdomain: !!this.request.headers.origin,
|
||||
secure: !!this.request.connection.encrypted,
|
||||
issued: +(new Date),
|
||||
@@ -241,7 +242,7 @@ Socket.prototype.leave = function(room, fn){
|
||||
this.adapter.del(this.id, room, function(err){
|
||||
if (err) return fn && fn(err);
|
||||
debug('left room %s', room);
|
||||
self.rooms.splice(self.rooms.indexOf(room, 1));
|
||||
self.rooms.splice(self.rooms.indexOf(room), 1);
|
||||
fn && fn(null);
|
||||
});
|
||||
return this;
|
||||
@@ -255,6 +256,7 @@ Socket.prototype.leave = function(room, fn){
|
||||
|
||||
Socket.prototype.leaveAll = function(){
|
||||
this.adapter.delAll(this.id);
|
||||
this.rooms = [];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -293,6 +295,10 @@ Socket.prototype.onpacket = function(packet){
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.BINARY_ACK:
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.DISCONNECT:
|
||||
this.ondisconnect();
|
||||
break;
|
||||
@@ -336,9 +342,11 @@ Socket.prototype.ack = function(id){
|
||||
if (sent) return;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
debug('sending ack %j', args);
|
||||
|
||||
var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
|
||||
self.packet({
|
||||
id: id,
|
||||
type: parser.ACK,
|
||||
type: type,
|
||||
data: args
|
||||
});
|
||||
};
|
||||
@@ -372,10 +380,21 @@ Socket.prototype.ondisconnect = function(){
|
||||
this.onclose('client namespace disconnect');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles a client error.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onerror = function(err){
|
||||
this.emit('error', err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon closing. Called by `Client`.
|
||||
*
|
||||
* @param {String} reason
|
||||
* @param {Error} optional error object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
|
||||
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "socket.io",
|
||||
"version": "1.0.2",
|
||||
"version": "1.2.1",
|
||||
"description": "node.js realtime framework server",
|
||||
"keywords": [
|
||||
"realtime",
|
||||
@@ -13,17 +13,17 @@
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/LearnBoost/socket.io"
|
||||
"url": "git://github.com/Automattic/socket.io"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"engine.io": "1.2.1",
|
||||
"socket.io-parser": "2.1.5",
|
||||
"socket.io-client": "1.0.2",
|
||||
"socket.io-adapter": "0.2.0",
|
||||
"has-binary-data": "0.1.1",
|
||||
"engine.io": "1.4.3",
|
||||
"socket.io-parser": "2.2.2",
|
||||
"socket.io-client": "1.2.1",
|
||||
"socket.io-adapter": "0.3.1",
|
||||
"has-binary-data": "0.1.3",
|
||||
"debug": "0.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
BIN
test/fixtures/big.jpg
vendored
Normal file
BIN
test/fixtures/big.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 MiB |
174066
test/fixtures/big.json
vendored
Normal file
174066
test/fixtures/big.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ var ioc = require('socket.io-client');
|
||||
var request = require('supertest');
|
||||
var expect = require('expect.js');
|
||||
|
||||
// creates a socket.io client for the given server
|
||||
// Creates a socket.io client for the given server
|
||||
function client(srv, nsp, opts){
|
||||
if ('object' == typeof nsp) {
|
||||
opts = nsp;
|
||||
@@ -51,10 +51,21 @@ describe('socket.io', function(){
|
||||
expect(srv.eio.maxHttpBufferSize).to.eql(10);
|
||||
});
|
||||
|
||||
it('should be able to set path with setting resource', function() {
|
||||
var srv = io(http());
|
||||
srv.set('resource', '/random');
|
||||
expect(srv.path()).to.be('/random');
|
||||
it('should be able to set path with setting resource', function(done) {
|
||||
var eio = io();
|
||||
var srv = http();
|
||||
|
||||
eio.set('resource', '/random');
|
||||
eio.attach(srv);
|
||||
|
||||
// Check that the server is accessible through the specified path
|
||||
request(srv)
|
||||
.get('/random/socket.io.js')
|
||||
.buffer(true)
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to set origins to engine.io', function() {
|
||||
@@ -116,7 +127,7 @@ describe('socket.io', function(){
|
||||
expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
|
||||
|
||||
// Address, xdomain, secure, issued and url set
|
||||
expect(s.handshake.address).to.not.be(undefined);
|
||||
expect(s.handshake.address).to.be('127.0.0.1');
|
||||
expect(s.handshake.xdomain).to.be.a('boolean');
|
||||
expect(s.handshake.secure).to.be.a('boolean');
|
||||
expect(s.handshake.issued).to.be.a('number');
|
||||
@@ -161,7 +172,7 @@ describe('socket.io', function(){
|
||||
io(srv);
|
||||
request(srv)
|
||||
.get('/socket.io/socket.io.js')
|
||||
.set('ETag', clientVersion)
|
||||
.set('If-None-Match', clientVersion)
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
expect(res.statusCode).to.be(304);
|
||||
@@ -259,146 +270,343 @@ describe('socket.io', function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow request when origin defined as function and same is supplied', function(done) {
|
||||
var sockets = io({ origins: function(origin,callback){
|
||||
if (origin == 'http://foo.example') {
|
||||
return callback(null, true);
|
||||
}
|
||||
return callback(null, false);
|
||||
} }).listen('54016');
|
||||
request.get('http://localhost:54016/socket.io/default/')
|
||||
.set('origin', 'http://foo.example')
|
||||
.query({ transport: 'polling' })
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow request when origin defined as function and different is supplied', function(done) {
|
||||
var sockets = io({ origins: function(origin,callback){
|
||||
if (origin == 'http://foo.example') {
|
||||
return callback(null, true);
|
||||
}
|
||||
return callback(null, false);
|
||||
} }).listen('54017');
|
||||
request.get('http://localhost:54017/socket.io/default/')
|
||||
.set('origin', 'http://herp.derp')
|
||||
.query({ transport: 'polling' })
|
||||
.end(function (err, res) {
|
||||
expect(res.status).to.be(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('close', function(){
|
||||
|
||||
it('should be able to close sio sending a srv', function(){
|
||||
var PORT = 54018;
|
||||
var srv = http().listen(PORT);
|
||||
var sio = io(srv);
|
||||
var net = require('net');
|
||||
var server = net.createServer();
|
||||
|
||||
var clientSocket = client(srv, { reconnection: false });
|
||||
|
||||
clientSocket.on('disconnect', function init() {
|
||||
expect(sio.nsps['/'].sockets.length).to.equal(0);
|
||||
server.listen(PORT);
|
||||
});
|
||||
|
||||
clientSocket.on('connect', function init() {
|
||||
expect(sio.nsps['/'].sockets.length).to.equal(1);
|
||||
sio.close();
|
||||
});
|
||||
|
||||
server.once('listening', function() {
|
||||
// PORT should be free
|
||||
server.close(function(error){
|
||||
expect(error).to.be(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should be able to close sio sending a port', function(){
|
||||
var PORT = 54019;
|
||||
var sio = io(PORT);
|
||||
var net = require('net');
|
||||
var server = net.createServer();
|
||||
|
||||
var clientSocket = ioc('ws://0.0.0.0:' + PORT);
|
||||
|
||||
clientSocket.on('disconnect', function init() {
|
||||
expect(sio.nsps['/'].sockets.length).to.equal(0);
|
||||
server.listen(PORT);
|
||||
});
|
||||
|
||||
clientSocket.on('connect', function init() {
|
||||
expect(sio.nsps['/'].sockets.length).to.equal(1);
|
||||
sio.close();
|
||||
});
|
||||
|
||||
server.once('listening', function() {
|
||||
// PORT should be free
|
||||
server.close(function(error){
|
||||
expect(error).to.be(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('namespaces', function(){
|
||||
var Socket = require('../lib/socket');
|
||||
var Namespace = require('../lib/namespace');
|
||||
|
||||
describe('default', function(){
|
||||
it('should be accessible through .sockets', function(){
|
||||
var sio = io();
|
||||
expect(sio.sockets).to.be.a(Namespace);
|
||||
});
|
||||
it('should be accessible through .sockets', function(){
|
||||
var sio = io();
|
||||
expect(sio.sockets).to.be.a(Namespace);
|
||||
});
|
||||
|
||||
it('should be aliased', function(){
|
||||
var sio = io();
|
||||
expect(sio.use).to.be.a('function');
|
||||
expect(sio.to).to.be.a('function');
|
||||
expect(sio['in']).to.be.a('function');
|
||||
expect(sio.emit).to.be.a('function');
|
||||
expect(sio.send).to.be.a('function');
|
||||
expect(sio.write).to.be.a('function');
|
||||
});
|
||||
it('should be aliased', function(){
|
||||
var sio = io();
|
||||
expect(sio.use).to.be.a('function');
|
||||
expect(sio.to).to.be.a('function');
|
||||
expect(sio['in']).to.be.a('function');
|
||||
expect(sio.emit).to.be.a('function');
|
||||
expect(sio.send).to.be.a('function');
|
||||
expect(sio.write).to.be.a('function');
|
||||
});
|
||||
|
||||
it('should automatically connect', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('connect', function(){
|
||||
done();
|
||||
});
|
||||
it('should automatically connect', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('connect', function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fire a `connection` event', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
done();
|
||||
});
|
||||
it('should fire a `connection` event', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fire a `connect` event', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connect', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
done();
|
||||
});
|
||||
it('should fire a `connect` event', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connect', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with many sockets', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
chat.on('connect', function(){
|
||||
--total || done();
|
||||
});
|
||||
news.on('connect', function(){
|
||||
--total || done();
|
||||
});
|
||||
it('should work with many sockets', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
sio.of('/chat');
|
||||
sio.of('/news');
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
chat.on('connect', function(){
|
||||
--total || done();
|
||||
});
|
||||
news.on('connect', function(){
|
||||
--total || done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with `of` and many sockets', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
sio.of('/news').on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
sio.of('/news').on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
it('should be able to equivalently start with "" or "/" on server', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var total = 2;
|
||||
sio.of('').on('connection', function(){
|
||||
--total || done();
|
||||
});
|
||||
sio.of('abc').on('connection', function(){
|
||||
--total || done();
|
||||
});
|
||||
var c1 = client(srv, '/');
|
||||
var c2 = client(srv, '/abc');
|
||||
});
|
||||
|
||||
it('should be equivalent for "" and "/" on client', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
sio.of('/').on('connection', function(){
|
||||
done();
|
||||
});
|
||||
var c1 = client(srv, '');
|
||||
});
|
||||
|
||||
it('should work with `of` and many sockets', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
sio.of('/news').on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
sio.of('/news').on('connection', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with `of` second param', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
sio.of('/news', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
sio.of('/news', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
it('should work with `of` second param', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
sio.of('/news', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
sio.of('/news', function(socket){
|
||||
expect(socket).to.be.a(Socket);
|
||||
--total || done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should disconnect upon transport disconnection', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
var totald = 2;
|
||||
var s;
|
||||
sio.of('/news', function(socket){
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
it('should disconnect upon transport disconnection', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var chat = client(srv, '/chat');
|
||||
var news = client(srv, '/news');
|
||||
var total = 2;
|
||||
var totald = 2;
|
||||
var s;
|
||||
sio.of('/news', function(socket){
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
sio.of('/chat', function(socket){
|
||||
s = socket;
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
--total || close();
|
||||
});
|
||||
sio.of('/chat', function(socket){
|
||||
s = socket;
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
function close(){
|
||||
s.disconnect(true);
|
||||
}
|
||||
--total || close();
|
||||
});
|
||||
function close(){
|
||||
s.disconnect(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should disconnect both default and custom namespace upon disconnect', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var lolcats = client(srv, '/lolcats');
|
||||
var total = 2;
|
||||
var totald = 2;
|
||||
var s;
|
||||
sio.of('/', function(socket){
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
});
|
||||
sio.of('/lolcats', function(socket){
|
||||
s = socket;
|
||||
socket.on('disconnect', function(reason){
|
||||
--totald || done();
|
||||
});
|
||||
--total || close();
|
||||
});
|
||||
function close(){
|
||||
s.disconnect(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should not crash while disconnecting socket', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv,'/ns');
|
||||
sio.on('connection', function(socket){
|
||||
socket.disconnect();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should return error connecting to non-existent namespace', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv,'/doesnotexist');
|
||||
socket.on('error', function(err) {
|
||||
expect(err).to.be('Invalid namespace');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('socket', function(){
|
||||
|
||||
it('should not fire events more than once after manually reconnecting', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var clientSocket = client(srv, { reconnection: false });
|
||||
clientSocket.on('connect', function init() {
|
||||
clientSocket.removeListener('connect', init);
|
||||
clientSocket.io.engine.close();
|
||||
|
||||
clientSocket.connect();
|
||||
clientSocket.on('connect', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fire reconnect_failed event more than once when server closed', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
|
||||
clientSocket.on('connect', function() {
|
||||
srv.close();
|
||||
});
|
||||
|
||||
clientSocket.on('reconnect_failed', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive events', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -431,6 +639,39 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should error with null messages', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.on('message', function(a){
|
||||
expect(a).to.be(null);
|
||||
done();
|
||||
});
|
||||
socket.send(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle transport null messages', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.on('error', function(err){
|
||||
expect(err).to.be.an(Error);
|
||||
s.on('disconnect', function(reason){
|
||||
expect(reason).to.be('client error');
|
||||
done();
|
||||
});
|
||||
});
|
||||
s.client.ondata(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -446,6 +687,28 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with utf8 multibyte character', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
var i = 0;
|
||||
socket.on('hoot', function(a){
|
||||
expect(a).to.be('utf8 — string');
|
||||
i++;
|
||||
|
||||
if (3 == i) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
s.emit('hoot', 'utf8 — string');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with binary data', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -570,6 +833,30 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive all events emitted from namespaced client immediately and in order', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var total = 0;
|
||||
srv.listen(function(){
|
||||
sio.of('/chat', function(s){
|
||||
s.on('hi', function(letter){
|
||||
total++;
|
||||
if (total == 2 && letter == 'b') {
|
||||
done();
|
||||
} else if (total == 1 && letter != 'a') {
|
||||
throw new Error('events out of order');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var chat = client(srv, '/chat');
|
||||
chat.emit('hi', 'a');
|
||||
setTimeout(function() {
|
||||
chat.emit('hi', 'b');
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit events with callbacks', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -746,6 +1033,59 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle very large json', function(done){
|
||||
this.timeout();
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var received = 0;
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.json)).to.be(false);
|
||||
if (++received == 3)
|
||||
done();
|
||||
else
|
||||
socket.emit('big', a);
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
|
||||
if (err) return done(err);
|
||||
data = JSON.parse(data);
|
||||
s.emit('big', {hello: 'friend', json: data});
|
||||
});
|
||||
s.on('big', function(a){
|
||||
s.emit('big', a);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle very large binary data', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var received = 0;
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
socket.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.image)).to.be(true);
|
||||
if (++received == 3)
|
||||
done();
|
||||
else
|
||||
socket.emit('big', a);
|
||||
});
|
||||
sio.on('connection', function(s){
|
||||
fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
|
||||
if (err) return done(err);
|
||||
s.emit('big', {hello: 'friend', image: data});
|
||||
});
|
||||
s.on('big', function(a){
|
||||
expect(Buffer.isBuffer(a.image)).to.be(true);
|
||||
s.emit('big', a);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('messaging many', function(){
|
||||
@@ -1013,15 +1353,38 @@ describe('socket.io', function(){
|
||||
expect(s.rooms).to.eql([s.id, 'a']);
|
||||
s.join('b', function(){
|
||||
expect(s.rooms).to.eql([s.id, 'a', 'b']);
|
||||
s.leave('b', function(){
|
||||
expect(s.rooms).to.eql([s.id, 'a']);
|
||||
done();
|
||||
s.join( 'c', function(){
|
||||
expect(s.rooms).to.eql([s.id, 'a', 'b', 'c']);
|
||||
s.leave('b', function(){
|
||||
expect(s.rooms).to.eql([s.id, 'a', 'c']);
|
||||
s.leaveAll();
|
||||
expect(s.rooms).to.eql([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes empty rooms', function(done) {
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
|
||||
srv.listen(function(){
|
||||
var socket = client(srv);
|
||||
sio.on('connection', function(s){
|
||||
s.join('a', function(){
|
||||
expect(s.nsp.adapter.rooms).to.have.key('a');
|
||||
s.leave('a', function(){
|
||||
expect(s.nsp.adapter.rooms).to.not.have.key('a');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('middleware', function(done){
|
||||
|
||||
Reference in New Issue
Block a user