Compare commits

...

96 Commits

Author SHA1 Message Date
Guillermo Rauch
6d5d7e4411 Release 1.4.1 2016-01-07 12:52:27 -08:00
Guillermo Rauch
ddb3445f3d Release 1.4.0 2016-01-05 15:44:48 -08:00
Guillermo Rauch
6eb9807f17 package: bump engine.io for sec advisory 2016-01-05 13:40:54 -08:00
Guillermo Rauch
7b0073c00f Merge pull request #2335 from nkzawa/patch-7
Improve the chat demo
2015-12-04 17:10:23 -08:00
nkzawa
0313ad0ea3 improve the chat demo 2015-12-05 10:07:08 +09:00
Guillermo Rauch
d310d42472 package: bump engine.io 2015-12-04 10:56:08 -08:00
Guillermo Rauch
709ceba00a package: bump socket.io-adapter for release 2015-12-03 10:28:33 -08:00
Guillermo Rauch
b29312bc61 package: bump engine.io for node 0.8 fix 2015-12-01 12:15:36 -08:00
Guillermo Rauch
51901160df package: temporarily revert version for tests 2015-12-01 11:24:06 -08:00
Guillermo Rauch
ab1b36e13f package: bump engine.io for ws memory fix 2015-11-30 08:16:21 -08:00
Guillermo Rauch
f7a2f35590 package: bump engine.io 2015-11-28 16:34:44 -08:00
Guillermo Rauch
c348737fe6 socket.io: increase large binary data test timeout 2015-11-28 15:13:13 -08:00
Guillermo Rauch
dde3737165 package: bump engine.io for release 2015-11-28 12:07:08 -08:00
Guillermo Rauch
8df4c7931b Merge pull request #2325 from darrachequesne/patch-2
Trigger callback even when joining an already joined room
2015-11-28 10:56:46 -08:00
Damien Arrachequesne
1dfacc6647 Trigger callback even when joining an already joined room 2015-11-27 22:08:18 +01:00
Guillermo Rauch
35a0fe0377 package: bump parser 2015-11-25 10:14:56 -08:00
Guillermo Rauch
3b00312fa7 namespace: clear rooms flag after a clients call (fixes #1978) 2015-11-23 09:40:57 -08:00
Guillermo Rauch
7b420295ef Merge pull request #2249 from pmq20/minqi-another
[Travis] Add Node 4.x to the test matrix
2015-11-23 09:31:48 -08:00
Guillermo Rauch
c504315982 Merge pull request #2322 from darrachequesne/issue-2199-clean
Add hasOwnProperty checks
2015-11-23 09:19:35 -08:00
Guillermo Rauch
520b5c37d5 Merge pull request #2321 from nkzawa/patch-6
Update redirects in README
2015-11-23 09:19:03 -08:00
Damien Arrachequesne
09f446eca0 Add hasOwnProperty checks 2015-11-23 15:12:21 +01:00
Naoyuki Kanezawa
aecf3bf71c Merge pull request #2218 from futbalguy/master
Clarified documentation of Socket.in
2015-11-23 17:37:07 +09:00
nkzawa
6c0a79e2b9 update redirects in README 2015-11-23 17:28:11 +09:00
Guillermo Rauch
8683206e31 Merge pull request #2239 from darrachequesne/issue-2199
converted arrays to objects
2015-11-22 10:34:57 -08:00
Guillermo Rauch
988d9d2346 Merge pull request #1999 from nkzawa/patch-3
Fix a few assertions are not executed properly
2015-11-22 10:17:02 -08:00
Damien Arrachequesne
b73d9bea4e converted arrays to objects 2015-11-22 11:12:40 +01:00
Naoyuki Kanezawa
d4fb6a5904 Merge pull request #2316 from tripu/master
Update “debug” to avoid vulnerability in “ms”
2015-11-22 10:39:23 +09:00
tripu
0517c609ba Avoid ^ in "debug" dependency (fixes #2314) 2015-11-21 23:59:16 +01:00
tripu
aa9438fee2 Update package "debug" to avoid "ms" vulnerability 2015-11-21 23:55:00 +01:00
Guillermo Rauch
aee466cc71 Update Readme.md 2015-11-21 10:54:19 -08:00
Guillermo Rauch
65f75d7732 Merge branch 'master' of github.com:socketio/socket.io 2015-11-21 10:46:26 -08:00
Guillermo Rauch
279c52a4c5 package: bump socket.io-parser 2015-11-21 10:45:43 -08:00
Naoyuki Kanezawa
67d1a67b1c Merge pull request #2319 from darrachequesne/patch-3
Minor fix
2015-11-21 23:21:39 +09:00
Damien Arrachequesne
aae68d74b1 Minor performance optimization 2015-11-20 22:03:03 +01:00
Damien Arrachequesne
bf5897cedc Fixed tests with large data 2015-11-20 22:01:16 +01:00
Damien Arrachequesne
a1a1c6657a Removed unused variable 2015-11-20 22:00:42 +01:00
Guillermo Rauch
2a4f7ae161 Merge pull request #2136 from nkzawa/patch-5
Don't set request property
2015-11-20 12:59:05 -08:00
Naoyuki Kanezawa
dba0576ca9 Merge pull request #2317 from ChaofengZhou/master
fixed a typo in the example code
2015-11-20 13:13:10 +09:00
Chaofeng
ba90f0991b fixed a typo in the example code 2015-11-19 21:09:34 -07:00
Guillermo Rauch
9a54e9cace package: bump mocha 2015-11-18 19:53:25 -08:00
Guillermo Rauch
9df4cb64b8 bump zuul-ngrok 2015-11-18 19:51:47 -08:00
Guillermo Rauch
c8f525868a package: bump has-binary 2015-11-18 16:56:06 -08:00
Guillermo Rauch
a39d7c2ae4 Merge pull request #2171 from KevinMartin/patch-1
Actually prevent double callbacks...
2015-11-18 12:56:01 -08:00
Guillermo Rauch
4ba266d404 Merge pull request #2307 from darrachequesne/patch-1
Upgrade npm version in order to fix node v0.8 build
2015-11-16 15:55:20 -08:00
Damien Arrachequesne
6b49779420 Upgrade npm version in order to fix node v0.8 build 2015-11-17 00:44:42 +01:00
Guillermo Rauch
b1775b1cb8 Merge pull request #2051 from tobalsgithub/master
Allowing a custom function for opts.allowRequest
2015-11-16 13:15:08 -08:00
Guillermo Rauch
ef52967301 Merge pull request #2271 from dazorni/master
Working travis build status
2015-11-16 13:12:26 -08:00
Guillermo Rauch
fde38b1bd7 Merge pull request #2208 from odeke-em/fix-legacy-repo-info
README: fixed up legacy repo links
2015-11-16 13:10:24 -08:00
Sebastian Zorn
75da57abb2 Working travis build status 2015-10-06 21:42:33 +02:00
Guillermo Rauch
21ea31a34e Merge branch '1.3.7-patch' 2015-09-21 04:30:59 +04:00
Guillermo Rauch
e2ebd4349b Release 1.3.7 2015-09-21 04:21:11 +04:00
Guillermo Rauch
b771f74a22 package: bump socket.io-client for node4 compatibility 2015-09-21 04:16:59 +04:00
Guillermo Rauch
8744007dc7 package: bump engine.io for node4 compatibility 2015-09-21 04:10:19 +04:00
P.S.V.R
3658928ee7 [Travis] Add Node 4.x to the test matrix 2015-09-16 17:39:26 +08:00
Guillermo Rauch
210e688732 package: bump engine.io 2015-09-09 15:47:14 -07:00
Guillermo Rauch
ae5420b727 package: bump engine.io and socket.io-client 2015-08-30 10:51:25 -07:00
futbalguy
d5b3bb46f8 Clarified documentation of Socket.in 2015-08-23 10:12:23 -07:00
Emmanuel Odeke
575d35a371 README: fixed up legacy repo links 2015-08-16 20:36:39 -06:00
Guillermo Rauch
e41483be9e Merge branch '1.3.6-patch' 2015-07-14 20:04:44 -07:00
Guillermo Rauch
c79e787671 test: better timeout for stress test 2015-07-14 19:58:42 -07:00
Guillermo Rauch
a2f6bb99d6 Merge branch '1.3.6-patch' 2015-07-14 18:02:56 -07:00
Guillermo Rauch
3e4061bfef Release 1.3.6 2015-07-14 17:59:50 -07:00
Guillermo Rauch
4c1d691fe5 package: bump engine.io to fix build on windows 2015-07-09 09:28:43 -07:00
Kevin Jose Martin
514aeb4fcd Actually prevent double callbacks...
We declare `sent = false` and even check `if (sent)` is truthy, but we never set it to truthy, therefore it never really *prevents double callbacks*...
2015-07-06 11:36:00 -04:00
Nathan Rajlich
876833198d Merge pull request #2111 from kemitchell/spdx-license
Use a Standard-Compliant License Identifier
2015-06-05 11:51:30 -07:00
Naoyuki Kanezawa
4d36d6c01a don't set request property 2015-05-30 03:34:05 +09:00
Guillermo Rauch
43fa075ec4 bump client 2015-05-27 22:56:15 -07:00
Guillermo Rauch
91c7bde34b Merge commit '342faf219793fc5c1f130fc33e3fb5422dab516d' 2015-05-27 22:55:15 -07:00
Guillermo Rauch
874a4a8535 package: bump client 2015-05-27 08:19:15 -07:00
Guillermo Rauch
93b571406e package: bump engine.io to fix build issues 2015-05-25 14:34:10 -07:00
Kyle Mitchell
98af793f07 use a valid SPDX license identifier 2015-05-05 00:08:44 +00:00
Guillermo Rauch
3f72dd3322 Merge pull request #2063 from kapouer/patch-1
Let adapter.add find connected socket
2015-04-10 21:38:41 -07:00
Guillermo Rauch
d0d38220fb Update Readme.md 2015-04-08 16:53:04 -07:00
Guillermo Rauch
f8aa157d5d remove proxy index file 2015-04-05 16:53:28 -07:00
Guillermo Rauch
0e13e9a268 bumped adapter 2015-04-05 15:52:59 -07:00
Guillermo Rauch
916872587f Merge pull request #2013 from nkzawa/namespace-flags
Supports flags on namespace
2015-04-05 15:51:54 -07:00
Guillermo Rauch
a7072845ea Merge pull request #2006 from nkzawa/patch-4
improve Socket#packet and Client#packet and enable volatile and compress when broadcast
2015-04-05 15:51:49 -07:00
Jérémy Lal
425409945b Let adapter.add find connected socket
When a socket connects, it joins its own room, resulting in a call to adapter.add.
The adapter in turn should be able to find the socket by id.
2015-03-24 14:54:52 +01:00
Guillermo Rauch
5826ef0bb5 Merge pull request #2059 from rase-/update/debug
Bump debug to 2.1.3
2015-03-17 16:42:00 -07:00
Tony Kovanen
14e32a9bad Bump debug to 2.1.3 2015-03-18 01:40:19 +02:00
TC
1dde0f3947 Allowing a custom function for opts.allowRequest 2015-03-12 15:50:31 -06:00
Guillermo Rauch
342faf2197 Release 1.3.5 2015-03-03 10:50:10 -08:00
Guillermo Rauch
12c6ee132d improve test 2015-03-03 10:34:56 -08:00
Guillermo Rauch
c9d909c993 package: bump socket.io-parser 2015-03-03 10:34:40 -08:00
Guillermo Rauch
125ab51338 test: added test for parser breakage 2015-03-03 10:08:26 -08:00
Guillermo Rauch
b31ac18554 test with 0.12 2015-02-19 15:38:35 -08:00
Naoyuki Kanezawa
53cdd8f1fc support flags on namespace 2015-02-20 03:34:09 +09:00
Naoyuki Kanezawa
81aea995ed improve Socket#packet and Client#packet 2015-02-15 04:33:20 +09:00
Guillermo Rauch
1b2d902f33 Release 1.3.4 2015-02-14 10:57:50 -08:00
Guillermo Rauch
9536437907 package: bump socket.io-client 2015-02-14 10:55:15 -08:00
Naoyuki Kanezawa
56fe26661d fix a few assertions 2015-02-12 06:09:30 +09:00
Guillermo Rauch
29974ac777 Release 1.3.3 2015-02-03 17:27:51 -08:00
Guillermo Rauch
ef23c74bea remove compression tests 2015-02-03 17:07:43 -08:00
Guillermo Rauch
49423d70bc added failing tests 2015-02-03 17:04:33 -08:00
Guillermo Rauch
715c7f99b4 socket: warn node_redis-style about missing error 2015-02-03 17:04:06 -08:00
Guillermo Rauch
f2ea965c6b package: bump parser 2015-02-03 16:32:48 -08:00
12 changed files with 380 additions and 123 deletions

View File

@@ -1,16 +1,20 @@
sudo: false
before_install:
- npm install -g npm@'>=1.4.3'
language: node_js
node_js:
- "0.8"
- "0.10"
- "0.11"
- "0.12"
- "4"
git:
depth: 1
matrix:
fast_finish: true
allow_failures:
- node_js: "0.11"
#matrix:
#fast_finish: true
#allow_failures:
#- node_js: "0.11"
notifications:
irc: "irc.freenode.org#socket.io"

View File

@@ -1,4 +1,64 @@
1.4.1 / 2016-01-07
==================
* version bump
1.4.0 / 2015-11-28
==================
* socket.io: increase large binary data test timeout
* package: bump `engine.io` for release
* trigger callback even when joining an already joined room
* package: bump parser
* namespace: clear rooms flag after a clients call (fixes #1978)
* package: bump `socket.io-parser`
* fixed tests with large data
* fixed a typo in the example code
* package: bump mocha
* package: bump `has-binary` and `zuul-ngrok`
* package: bump `engine.io` and `socket.io-client`
* README: clarified documentation of Socket.in
* README: fixed up legacy repo links
* test: better timeout for stress test
* socket: don't set request property which has a getter
* removed proxy index file
* support flags on namespace
* improve Socket#packet and Client#packet
* socket: warn node_redis-style about missing `error`
* test: added failing test
* test: increase timeout for large binary data test
* package: bump `has-binary` to work with all objects (fixes #1955)
* fix origin verification default https port [evanlucas]
* support compression [nkzawa]
1.3.7 / 2015-09-21
==================
* package: bump `socket.io-client` for node4 compatibility
* package: bump `engine.io` for node4 compatibility
1.3.6 / 2015-07-14
==================
* package: bump `engine.io` to fix build on windows
1.3.5 / 2015-03-03
==================
* package: bump `socket.io-parser`
1.3.4 / 2015-02-14
==================
* package: bump `socket.io-client`
1.3.3 / 2015-02-03
==================
* socket: warn node_redis-style about missing `error`
* package: bump parser to better handle bad binary packets
1.3.2 / 2015-01-19
==================

View File

@@ -1,9 +1,10 @@
# socket.io
[![Build Status](https://secure.travis-ci.org/Automattic/socket.io.svg)](http://travis-ci.org/Automattic/socket.io)
[![Build Status](https://secure.travis-ci.org/socketio/socket.io.svg)](https://travis-ci.org/socketio/socket.io)
![NPM version](https://badge.fury.io/js/socket.io.svg)
![Downloads](http://img.shields.io/npm/dm/socket.io.svg?style=flat)
![Downloads](https://img.shields.io/npm/dm/socket.io.svg?style=flat)
[![](http://slack.socket.io/badge.svg?)](http://slack.socket.io)
## How to use
@@ -85,7 +86,7 @@ server.listen(3000);
The same options passed to socket.io are always passed to
the `engine.io` `Server` that gets created. See engine.io
[options](https://github.com/learnboost/engine.io#methods-1)
[options](https://github.com/socketio/engine.io#methods-1)
as reference.
### Server(srv:http#Server, opts:Object)
@@ -127,7 +128,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/Automattic/socket.io-adapter).
[socket.io-adapter](https://github.com/socketio/socket.io-adapter).
If no arguments are supplied this method returns the current value.
@@ -144,7 +145,7 @@ server.listen(3000);
__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/)
* 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/expressjs/cors)
### Server#sockets:Namespace
@@ -347,7 +348,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/Automattic/socket.io-adapter).
[socket.io-adapter](https://github.com/socketio/socket.io-adapter).
### Socket#leave(name:String[, fn:Function]):Socket
@@ -358,10 +359,9 @@ 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/Automattic/socket.io-adapter).
[socket.io-adapter](https://github.com/socketio/socket.io-adapter).
### Socket#to(room:String):Socket
### Socket#in(room:String):Socket
Sets a modifier for a subsequent event emission that the event will
only be _broadcasted_ to sockets that have joined the given `room`.
@@ -375,6 +375,10 @@ server.listen(3000);
});
```
### Socket#in(room:String):Socket
Same as `Socket#to`
### Socket#compress(v:Boolean):Socket
Sets a modifier for a subsequent event emission that the event data will
@@ -405,7 +409,7 @@ server.listen(3000);
## Debug / logging
Socket.IO is powered by [debug](http://github.com/visionmedia/debug).
Socket.IO is powered by [debug](https://github.com/visionmedia/debug).
In order to see all the debug output, run your app with the environment variable
`DEBUG` including the desired scope.

View File

@@ -14,8 +14,6 @@ app.use(express.static(__dirname + '/public'));
// Chatroom
// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;
io.on('connection', function (socket) {
@@ -32,10 +30,10 @@ io.on('connection', function (socket) {
// when the client emits 'add user', this listens and executes
socket.on('add user', function (username) {
if (addedUser) return;
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
++numUsers;
addedUser = true;
socket.emit('login', {
@@ -64,9 +62,7 @@ io.on('connection', function (socket) {
// when the user disconnects.. perform this
socket.on('disconnect', function () {
// remove the username from global usernames list
if (addedUser) {
delete usernames[socket.username];
--numUsers;
// echo globally that this client has left

View File

@@ -7,7 +7,7 @@ $(function() {
'#3b88eb', '#3824aa', '#a700ff', '#d300e7'
];
// Initialize varibles
// Initialize variables
var $window = $(window);
var $usernameInput = $('.usernameInput'); // Input for username
var $messages = $('.messages'); // Messages area

View File

@@ -1,2 +0,0 @@
module.exports = require('./lib');

View File

@@ -28,7 +28,7 @@ function Client(server, conn){
this.id = conn.id;
this.request = conn.request;
this.setup();
this.sockets = [];
this.sockets = {};
this.nsps = {};
this.connectBuffer = [];
}
@@ -60,11 +60,12 @@ 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'}, false, false, true);
var nsp = this.server.nsps[name];
if (!nsp) {
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;
@@ -72,7 +73,7 @@ Client.prototype.connect = function(name){
var self = this;
var socket = nsp.add(this, function(){
self.sockets.push(socket);
self.sockets[socket.id] = socket;
self.nsps[nsp.name] = socket;
if ('/' == nsp.name && self.connectBuffer.length > 0) {
@@ -89,12 +90,12 @@ Client.prototype.connect = function(name){
*/
Client.prototype.disconnect = function(){
var socket;
// we don't use a for loop because the length of
// `sockets` changes upon each iteration
while (socket = this.sockets.shift()) {
socket.disconnect();
for (var id in this.sockets) {
if (this.sockets.hasOwnProperty(id)) {
this.sockets[id].disconnect();
}
}
this.sockets = {};
this.close();
};
@@ -105,10 +106,9 @@ Client.prototype.disconnect = function(){
*/
Client.prototype.remove = function(socket){
var i = this.sockets.indexOf(socket);
if (~i) {
var nsp = this.sockets[i].nsp.name;
this.sockets.splice(i, 1);
if (this.sockets.hasOwnProperty(socket.id)) {
var nsp = this.sockets[socket.id].nsp.name;
delete this.sockets[socket.id];
delete this.nsps[nsp];
} else {
debug('ignoring remove for %s', socket.id);
@@ -133,26 +133,25 @@ Client.prototype.close = function(){
* Writes a packet to the transport.
*
* @param {Object} packet object
* @param {Boolean} whether packet is already encoded
* @param {Boolean} whether packet is volatile
* @param {Boolean} whether packet should be compressed
* @param {Object} options
* @api private
*/
Client.prototype.packet = function(packet, preEncoded, volatile, compress){
Client.prototype.packet = function(packet, opts){
opts = opts || {};
var self = this;
// this writes to the actual connection
function writeToEngine(encodedPackets) {
if (volatile && !self.conn.transport.writable) return;
if (opts.volatile && !self.conn.transport.writable) return;
for (var i = 0; i < encodedPackets.length; i++) {
self.conn.write(encodedPackets[i], { compress: compress });
self.conn.write(encodedPackets[i], { compress: opts.compress });
}
}
if ('open' == this.conn.readyState) {
debug('writing packet %j', packet);
if(!preEncoded) { // not broadcasting, need to encode
if (!opts.preEncoded) { // not broadcasting, need to encode
this.encoder.encode(packet, function (encodedPackets) { // encode, then write results to engine
writeToEngine(encodedPackets);
});
@@ -206,9 +205,11 @@ Client.prototype.ondecoded = function(packet) {
*/
Client.prototype.onerror = function(err){
this.sockets.forEach(function(socket){
socket.onerror(err);
});
for (var id in this.sockets) {
if (this.sockets.hasOwnProperty(id)) {
this.sockets[id].onerror(err);
}
}
this.onclose('client error');
};
@@ -226,10 +227,12 @@ Client.prototype.onclose = function(reason){
this.destroy();
// `nsps` and `sockets` are cleaned up seamlessly
var socket;
while (socket = this.sockets.shift()) {
socket.onclose(reason);
for (var id in this.sockets) {
if (this.sockets.hasOwnProperty(id)) {
this.sockets[id].onclose(reason);
}
}
this.sockets = {};
this.decoder.destroy(); // clean up decoder
};

View File

@@ -222,7 +222,7 @@ Server.prototype.attach = function(srv, opts){
opts = opts || {};
opts.path = opts.path || this.path();
// set origins verification
opts.allowRequest = this.checkRequest.bind(this);
opts.allowRequest = opts.allowRequest || this.checkRequest.bind(this);
// initialize engine
debug('creating engine.io instance with opts %j', opts);
@@ -330,13 +330,14 @@ Server.prototype.onconnection = function(conn){
Server.prototype.of = function(name, fn){
if (String(name)[0] !== '/') name = '/' + name;
if (!this.nsps[name]) {
var nsp = this.nsps[name];
if (!nsp) {
debug('initializing namespace %s', name);
var nsp = new Namespace(this, name);
nsp = new Namespace(this, name);
this.nsps[name] = nsp;
}
if (fn) this.nsps[name].on('connect', fn);
return this.nsps[name];
if (fn) nsp.on('connect', fn);
return nsp;
};
/**
@@ -346,9 +347,11 @@ Server.prototype.of = function(name, fn){
*/
Server.prototype.close = function(){
this.nsps['/'].sockets.forEach(function(socket){
socket.onclose();
});
for (var id in this.nsps['/'].sockets) {
if (this.nsps['/'].sockets.hasOwnProperty(id)) {
this.nsps['/'].sockets[id].onclose();
}
}
this.engine.close();
@@ -361,7 +364,7 @@ Server.prototype.close = function(){
* Expose main namespace (/).
*/
['on', 'to', 'in', 'use', 'emit', 'send', 'write', 'clients'].forEach(function(fn){
['on', 'to', 'in', 'use', 'emit', 'send', 'write', 'clients', 'compress'].forEach(function(fn){
Server.prototype[fn] = function(){
var nsp = this.sockets[fn];
return nsp.apply(this.sockets, arguments);
@@ -369,8 +372,9 @@ Server.prototype.close = function(){
});
Namespace.flags.forEach(function(flag){
Server.prototype.__defineGetter__(flag, function(name){
this.flags.push(name);
Server.prototype.__defineGetter__(flag, function(){
this.sockets.flags = this.sockets.flags || {};
this.sockets.flags[flag] = true;
return this;
});
});

View File

@@ -29,7 +29,10 @@ exports.events = [
* Flags.
*/
exports.flags = ['json'];
exports.flags = [
'json',
'volatile'
];
/**
* `EventEmitter#emit` reference.
@@ -48,11 +51,10 @@ var emit = Emitter.prototype.emit;
function Namespace(server, name){
this.name = name;
this.server = server;
this.sockets = [];
this.sockets = {};
this.connected = {};
this.fns = [];
this.ids = 0;
this.acks = {};
this.initAdapter();
}
@@ -158,7 +160,7 @@ Namespace.prototype.add = function(client, fn){
if (err) return socket.error(err.data || err.message);
// track socket
self.sockets.push(socket);
self.sockets[socket.id] = socket;
// it's paramount that the internal `onconnect` logic
// fires before user-set events to prevent state order
@@ -185,9 +187,8 @@ Namespace.prototype.add = function(client, fn){
*/
Namespace.prototype.remove = function(socket){
var i = this.sockets.indexOf(socket);
if (~i) {
this.sockets.splice(i, 1);
if (this.sockets.hasOwnProperty(socket.id)) {
delete this.sockets[socket.id];
} else {
debug('ignoring remove for %s', socket.id);
}
@@ -250,5 +251,22 @@ Namespace.prototype.write = function(){
Namespace.prototype.clients = function(fn){
this.adapter.clients(this.rooms, fn);
// delete rooms flag for scenario:
// .in('room').clients() (GH-1978)
delete this.rooms;
return this;
};
/**
* Sets the compress flag.
*
* @param {Boolean} if `true`, compresses the sending data
* @return {Socket} self
* @api public
*/
Namespace.prototype.compress = function(compress){
this.flags = this.flags || {};
this.flags.compress = compress;
return this;
};

View File

@@ -59,11 +59,10 @@ function Socket(nsp, client){
this.nsp = nsp;
this.server = nsp.server;
this.adapter = this.nsp.adapter;
this.id = client.id;
this.request = client.request;
this.id = nsp.name + '#' + client.id;
this.client = client;
this.conn = client.conn;
this.rooms = [];
this.rooms = {};
this.acks = {};
this.connected = true;
this.disconnected = false;
@@ -132,10 +131,11 @@ Socket.prototype.emit = function(ev){
var packet = {};
packet.type = hasBin(args) ? parser.BINARY_EVENT : parser.EVENT;
packet.data = args;
var flags = this.flags || {};
// access last argument to see if it's an ACK callback
if ('function' == typeof args[args.length - 1]) {
if (this._rooms || (this.flags && this.flags.broadcast)) {
if (this._rooms || flags.broadcast) {
throw new Error('Callbacks are not supported when broadcasting');
}
@@ -144,15 +144,18 @@ Socket.prototype.emit = function(ev){
packet.id = this.nsp.ids++;
}
if (this._rooms || (this.flags && this.flags.broadcast)) {
if (this._rooms || flags.broadcast) {
this.adapter.broadcast(packet, {
except: [this.id],
rooms: this._rooms,
flags: this.flags
flags: flags
});
} else {
// dispatch packet
this.packet(packet);
this.packet(packet, {
volatile: flags.volatile,
compress: flags.compress
});
}
// reset flags
@@ -196,14 +199,15 @@ Socket.prototype.write = function(){
* Writes a packet.
*
* @param {Object} packet object
* @param {Object} options
* @api private
*/
Socket.prototype.packet = function(packet, preEncoded){
Socket.prototype.packet = function(packet, opts){
packet.nsp = this.nsp.name;
var volatile = this.flags && this.flags.volatile;
var compress = !this.flags || false !== this.flags.compress;
this.client.packet(packet, preEncoded, volatile, compress);
opts = opts || {};
opts.compress = false !== opts.compress;
this.client.packet(packet, opts);
};
/**
@@ -218,11 +222,14 @@ Socket.prototype.packet = function(packet, preEncoded){
Socket.prototype.join = function(room, fn){
debug('joining room %s', room);
var self = this;
if (~this.rooms.indexOf(room)) return this;
if (this.rooms.hasOwnProperty(room)) {
fn && fn(null);
return this;
}
this.adapter.add(this.id, room, function(err){
if (err) return fn && fn(err);
debug('joined room %s', room);
self.rooms.push(room);
self.rooms[room] = room;
fn && fn(null);
});
return this;
@@ -243,10 +250,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);
var idx = self.rooms.indexOf(room);
if (idx >= 0) {
self.rooms.splice(idx, 1);
}
delete self.rooms[room];
fn && fn(null);
});
return this;
@@ -260,7 +264,7 @@ Socket.prototype.leave = function(room, fn){
Socket.prototype.leaveAll = function(){
this.adapter.delAll(this.id);
this.rooms = [];
this.rooms = {};
};
/**
@@ -272,9 +276,9 @@ Socket.prototype.leaveAll = function(){
Socket.prototype.onconnect = function(){
debug('socket connected - writing packet');
this.nsp.connected[this.id] = this;
this.join(this.id);
this.packet({ type: parser.CONNECT });
this.nsp.connected[this.id] = this;
};
/**
@@ -353,6 +357,8 @@ Socket.prototype.ack = function(id){
type: type,
data: args
});
sent = true;
};
};

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "1.3.2",
"version": "1.4.1",
"description": "node.js realtime framework server",
"keywords": [
"realtime",
@@ -11,6 +11,8 @@
"socket",
"io"
],
"main": "./lib/index",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/Automattic/socket.io"
@@ -19,19 +21,20 @@
"test": "mocha --reporter dot --slow 200ms --bail"
},
"dependencies": {
"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"
"engine.io": "1.6.5",
"socket.io-parser": "2.2.6",
"socket.io-client": "1.4.1",
"socket.io-adapter": "0.4.0",
"has-binary": "0.1.7",
"debug": "2.2.0"
},
"devDependencies": {
"mocha": "1.16.2",
"expect.js": "0.3.1",
"supertest": "0.8.2",
"istanbul": "0.2.3",
"mocha": "2.3.4",
"superagent": "0.17.0",
"istanbul": "0.2.3"
"supertest": "0.8.2",
"zuul-ngrok": "3.1.0"
},
"contributors": [
{

View File

@@ -328,6 +328,32 @@ describe('socket.io', function(){
done();
});
});
it('should allow request if custom function in opts.allowRequest returns true', function(done){
var sockets = io(http().listen(54022), { allowRequest: function (req, callback) {
return callback(null, true);
}, origins: 'http://foo.example:*' });
request.get('http://localhost:54022/socket.io/default/')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(200);
done();
});
});
it('should disallow request if custom function in opts.allowRequest returns false', function(done){
var sockets = io(http().listen(54023), { allowRequest: function (req, callback) {
return callback(null, false);
} });
request.get('http://localhost:54023/socket.io/default/')
.set('origin', 'http://foo.example')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(400);
done();
});
});
});
describe('close', function(){
@@ -342,12 +368,12 @@ describe('socket.io', function(){
var clientSocket = client(srv, { reconnection: false });
clientSocket.on('disconnect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(0);
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);
server.listen(PORT);
});
clientSocket.on('connect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(1);
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);
sio.close();
});
@@ -369,12 +395,12 @@ describe('socket.io', function(){
var clientSocket = ioc('ws://0.0.0.0:' + PORT);
clientSocket.on('disconnect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(0);
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);
server.listen(PORT);
});
clientSocket.on('connect', function init() {
expect(sio.nsps['/'].sockets.length).to.equal(1);
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);
sio.close();
});
@@ -405,6 +431,12 @@ describe('socket.io', function(){
expect(sio.emit).to.be.a('function');
expect(sio.send).to.be.a('function');
expect(sio.write).to.be.a('function');
expect(sio.clients).to.be.a('function');
expect(sio.compress).to.be.a('function');
expect(sio.json).to.be(sio);
expect(sio.volatile).to.be(sio);
expect(sio.sockets.flags).to.eql({ json: true, volatile: true });
delete sio.sockets.flags;
});
it('should automatically connect', function(done){
@@ -636,7 +668,7 @@ describe('socket.io', function(){
});
function getClients() {
sio.of('/chat').clients(function(error, sids) {
expect(error).to.be.undefined;
expect(error).to.not.be.ok();
expect(sids).to.contain(chatSids[0]);
expect(sids).to.contain(chatSids[1]);
expect(sids).to.not.contain(otherSid);
@@ -679,7 +711,7 @@ describe('socket.io', function(){
});
function getClients() {
sio.of('/chat').in('foo').clients(function(error, sids) {
expect(error).to.be.undefined;
expect(error).to.not.be.ok();
expect(sids).to.contain(chatFooSid);
expect(sids).to.not.contain(chatBarSid);
expect(sids).to.not.contain(otherSid);
@@ -722,7 +754,7 @@ describe('socket.io', function(){
});
function getClients() {
sio.of('/chat').clients(function(error, sids) {
expect(error).to.be.undefined;
expect(error).to.not.be.ok();
expect(sids).to.contain(chatFooSid);
expect(sids).to.contain(chatBarSid);
expect(sids).to.not.contain(otherSid);
@@ -730,6 +762,87 @@ describe('socket.io', function(){
});
}
});
it('should not emit volatile event after regular event', function(done) {
var srv = http();
var sio = io(srv);
var counter = 0;
srv.listen(function(){
sio.of('/chat').on('connection', function(s){
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(function() {
sio.of('/chat').emit('ev', 'data');
sio.of('/chat').volatile.emit('ev', 'data');
}, 20);
});
var socket = client(srv, '/chat');
socket.on('ev', function() {
counter++;
});
});
setTimeout(function() {
expect(counter).to.be(1);
done();
}, 200);
});
it('should emit volatile event', function(done) {
var srv = http();
var sio = io(srv);
var counter = 0;
srv.listen(function(){
sio.of('/chat').on('connection', function(s){
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(function() {
sio.of('/chat').volatile.emit('ev', 'data');
}, 20);
});
var socket = client(srv, '/chat');
socket.on('ev', function() {
counter++;
});
});
setTimeout(function() {
expect(counter).to.be(1);
done();
}, 200);
});
it('should enable compression by default', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv, '/chat');
sio.of('/chat').on('connection', function(s){
s.conn.once('packetCreate', function(packet) {
expect(packet.options.compress).to.be(true);
done();
});
sio.of('/chat').emit('woot', 'hi');
});
});
});
it('should disable compression', function(done){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv, '/chat');
sio.of('/chat').on('connection', function(s){
s.conn.once('packetCreate', function(packet) {
expect(packet.options.compress).to.be(false);
done();
});
sio.of('/chat').compress(false).emit('woot', 'hi');
});
});
});
});
describe('socket', function(){
@@ -1398,7 +1511,7 @@ describe('socket.io', function(){
it('should handle very large json', function(done){
this.timeout(30000);
var srv = http();
var sio = io(srv);
var sio = io(srv, { perMessageDeflate: false });
var received = 0;
srv.listen(function(){
var socket = client(srv);
@@ -1423,10 +1536,9 @@ describe('socket.io', function(){
});
it('should handle very large binary data', function(done){
this.timeout(10000);
this.timeout(30000);
var srv = http();
var sio = io(srv);
var sio = io(srv, { perMessageDeflate: false });
var received = 0;
srv.listen(function(){
var socket = client(srv);
@@ -1480,13 +1592,13 @@ describe('socket.io', function(){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
var socket = client(srv, '/chat');
sio.of('/chat').on('connection', function(s){
s.conn.once('packetCreate', function(packet) {
expect(packet.options.compress).to.be(true);
done();
});
s.emit('woot', 'hi');
sio.of('/chat').emit('woot', 'hi');
});
});
});
@@ -1495,13 +1607,13 @@ describe('socket.io', function(){
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
var socket = client(srv, '/chat');
sio.of('/chat').on('connection', function(s){
s.conn.once('packetCreate', function(packet) {
expect(packet.options.compress).to.be(false);
done();
});
s.compress(false).emit('woot', 'hi');
sio.of('/chat').compress(false).emit('woot', 'hi');
});
});
});
@@ -1539,6 +1651,55 @@ describe('socket.io', function(){
});
});
});
it('should handle empty binary packet', 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('5');
});
});
});
});
it('should not crash when messing with Object prototype', function(done){
Object.prototype.foo = 'bar';
var srv = http();
var sio = io(srv);
srv.listen(function(){
var socket = client(srv);
sio.on('connection', function(s){
s.disconnect(true);
sio.close();
setTimeout(function(){
done();
}, 100);
});
});
});
it('should always trigger the callback (if provided) when joining a room', 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(){
s.join('a', done);
});
});
});
});
});
describe('messaging many', function(){
@@ -1803,15 +1964,15 @@ describe('socket.io', function(){
var socket = client(srv);
sio.on('connection', function(s){
s.join('a', function(){
expect(s.rooms).to.eql([s.id, 'a']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
s.join('b', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
s.join( 'c', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b', 'c']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b', 'c']);
s.leave('b', function(){
expect(s.rooms).to.eql([s.id, 'a', 'c']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'c']);
s.leaveAll();
expect(s.rooms).to.eql([]);
expect(Object.keys(s.rooms)).to.eql([]);
done();
});
});
@@ -1847,13 +2008,13 @@ describe('socket.io', function(){
var socket = client(srv);
sio.on('connection', function(s){
s.join('a', function(){
expect(s.rooms).to.eql([s.id, 'a']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
s.join('b', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
s.leave('unknown', function(){
expect(s.rooms).to.eql([s.id, 'a', 'b']);
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
s.leaveAll();
expect(s.rooms).to.eql([]);
expect(Object.keys(s.rooms)).to.eql([]);
done();
});
});