mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-11 07:58:13 -05:00
Compare commits
122 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
338c1da63d | ||
|
|
0abbd4da50 | ||
|
|
c89ccd9b97 | ||
|
|
a646044f34 | ||
|
|
751a6fc34a | ||
|
|
1f59e4526a | ||
|
|
0a7afa85ea | ||
|
|
1e31769062 | ||
|
|
797c9a3498 | ||
|
|
4f93a0b429 | ||
|
|
3c98130f15 | ||
|
|
9c23308c6e | ||
|
|
955e5e0d91 | ||
|
|
0ef55b26d4 | ||
|
|
4d8e2d342c | ||
|
|
d48f848bb4 | ||
|
|
57b386385e | ||
|
|
9e7567daee | ||
|
|
2e36799b17 | ||
|
|
9bb5e9de2f | ||
|
|
ff2c15de68 | ||
|
|
a483658607 | ||
|
|
4c5dbd8824 | ||
|
|
e14a10b7ce | ||
|
|
5a123beea5 | ||
|
|
2ed5f0f5fb | ||
|
|
e9f980c475 | ||
|
|
6f44f3a8ef | ||
|
|
04fc0f3677 | ||
|
|
d026c00d05 | ||
|
|
fdf64cc38f | ||
|
|
5badb6436e | ||
|
|
c20e0b26c9 | ||
|
|
5c10c5439b | ||
|
|
8182ecc61c | ||
|
|
ccd3376627 | ||
|
|
58a73d39e9 | ||
|
|
e60bd5a4da | ||
|
|
21dffa4b58 | ||
|
|
94852e3d23 | ||
|
|
b8c60506a6 | ||
|
|
ecc76f48bc | ||
|
|
c94058f9b0 | ||
|
|
43d9a4b55d | ||
|
|
df916172dd | ||
|
|
271c625243 | ||
|
|
628fe8f1b2 | ||
|
|
db62e1bf67 | ||
|
|
ba4c7921ef | ||
|
|
30ea0b8d7d | ||
|
|
2d141aff7c | ||
|
|
40763d3962 | ||
|
|
2a092bd2fb | ||
|
|
4137eb5c43 | ||
|
|
e3207005da | ||
|
|
42aa77614e | ||
|
|
1491a96c95 | ||
|
|
0c6d50d9c0 | ||
|
|
881f16553c | ||
|
|
e5a8d4d2d9 | ||
|
|
fb0253edea | ||
|
|
3c5f5a0864 | ||
|
|
a23d26a617 | ||
|
|
910b5d77a6 | ||
|
|
438ad63cdf | ||
|
|
7e9a67d8ee | ||
|
|
0ae070885d | ||
|
|
36d99d8d84 | ||
|
|
0e63b0910e | ||
|
|
3c7350fa58 | ||
|
|
aadd5da655 | ||
|
|
6d4128750b | ||
|
|
6edcd1c6ba | ||
|
|
6b2394e612 | ||
|
|
677af3fa11 | ||
|
|
a1ff739b36 | ||
|
|
de5b588e17 | ||
|
|
5a20c1195b | ||
|
|
5253bc400b | ||
|
|
1245a5639e | ||
|
|
88161539a1 | ||
|
|
d99d4d15ae | ||
|
|
06ecfe5444 | ||
|
|
e90b4eba1e | ||
|
|
c7de1a1adf | ||
|
|
7bae6ac636 | ||
|
|
355b5156fe | ||
|
|
3e168ee0b8 | ||
|
|
ed9ab77dcb | ||
|
|
1104cd135e | ||
|
|
0be915cd0f | ||
|
|
c6dd41b915 | ||
|
|
0f14312d7b | ||
|
|
97bd95f036 | ||
|
|
11e0f19272 | ||
|
|
e388a3319d | ||
|
|
b551ce9835 | ||
|
|
0bac96a6b2 | ||
|
|
1d07b10339 | ||
|
|
398b5479f0 | ||
|
|
d9eb729eab | ||
|
|
f9db72997f | ||
|
|
1293505dc2 | ||
|
|
f4e9e71c56 | ||
|
|
045674de97 | ||
|
|
7091acf24c | ||
|
|
19341051e8 | ||
|
|
e141e09aaf | ||
|
|
5fabe4e780 | ||
|
|
7760a71d90 | ||
|
|
c077357eff | ||
|
|
2f26a2bdb4 | ||
|
|
13af610f6d | ||
|
|
abcedf53ec | ||
|
|
24456fdcbe | ||
|
|
25116ab179 | ||
|
|
a116d52e30 | ||
|
|
cecf5f127e | ||
|
|
1c467e15e6 | ||
|
|
a110542563 | ||
|
|
7d55724468 | ||
|
|
1d84c55743 |
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
*Note*: for support questions, please use one of these channels: [stackoverflow](http://stackoverflow.com/questions/tagged/socket.io) or [slack](https://socketio.slack.com)
|
||||
|
||||
### You want to:
|
||||
|
||||
* [x] report a *bug*
|
||||
* [ ] request a *feature*
|
||||
|
||||
### Current behaviour
|
||||
|
||||
|
||||
### Steps to reproduce (if the current behaviour is a bug)
|
||||
|
||||
|
||||
### Expected behaviour
|
||||
|
||||
|
||||
### Setup
|
||||
- OS:
|
||||
- browser:
|
||||
- socket.io version:
|
||||
|
||||
### Other information (e.g. stacktraces, related issues, suggestions how to fix)
|
||||
|
||||
|
||||
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
### The kind of change this PR does introduce
|
||||
|
||||
* [x] a bug fix
|
||||
* [ ] a new feature
|
||||
* [ ] an update to the documentation
|
||||
* [ ] a code change that improves performance
|
||||
* [ ] other
|
||||
|
||||
### Current behaviour
|
||||
|
||||
|
||||
### New behaviour
|
||||
|
||||
|
||||
### Other information (e.g. related issues)
|
||||
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,4 +9,5 @@ lib-cov
|
||||
benchmarks/*.png
|
||||
node_modules
|
||||
coverage
|
||||
.idea
|
||||
.idea
|
||||
dist
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
support
|
||||
test
|
||||
examples
|
||||
.gitignore
|
||||
10
.travis.yml
10
.travis.yml
@@ -3,14 +3,22 @@ before_install:
|
||||
- npm install -g npm@'>=1.4.3'
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "node"
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- node_js: '0.10'
|
||||
env: TEST_VERSION=compat
|
||||
- node_js: '0.12'
|
||||
env: TEST_VERSION=compat
|
||||
- node_js: '4'
|
||||
env: TEST_VERSION=compat
|
||||
#matrix:
|
||||
#fast_finish: true
|
||||
#allow_failures:
|
||||
|
||||
87
History.md
87
History.md
@@ -1,4 +1,91 @@
|
||||
|
||||
1.7.4 / 2017-05-07
|
||||
===================
|
||||
|
||||
* [chore] Bump engine.io to version 1.8.4
|
||||
|
||||
1.7.3 / 2017-02-17
|
||||
===================
|
||||
|
||||
* [chore] Bump engine.io to version 1.8.3
|
||||
|
||||
1.7.2 / 2016-12-11
|
||||
===================
|
||||
|
||||
* [chore] Bump engine.io to version 1.8.2 (#2782)
|
||||
* [fix] Fixes socket.use error packet (#2772)
|
||||
|
||||
1.7.1 / 2016-11-28
|
||||
===================
|
||||
|
||||
1.7.0 / 2016-11-27
|
||||
===================
|
||||
|
||||
* [docs] Comment connected socket availability for adapters (#2081)
|
||||
* [docs] Fixed grammar issues in the README.md (#2159)
|
||||
* [feature] serve sourcemap for socket.io-client (#2482)
|
||||
* [feature] Add a `local` flag (#2628)
|
||||
* [chore] Bump engine.io to version 1.8.1 (#2765)
|
||||
* [chore] Update client location and serve minified file (#2766)
|
||||
|
||||
1.6.0 / 2016-11-20
|
||||
==================
|
||||
|
||||
* [fix] Make ETag header comply with standard. (#2603)
|
||||
* [feature] Loading client script on demand. (#2567)
|
||||
* [test] Fix leaking clientSocket (#2721)
|
||||
* [feature] Add support for all event emitter methods (#2601)
|
||||
* [chore] Update year to 2016 (#2456)
|
||||
* [feature] Add support for socket middleware (#2306)
|
||||
* [feature] add support for Server#close(callback) (#2748)
|
||||
* [fix] Don't drop query variables on handshake (#2745)
|
||||
* [example] Add disconnection/reconnection logs to the chat example (#2675)
|
||||
* [perf] Minor code optimizations (#2219)
|
||||
* [chore] Bump debug to version 2.3.3 (#2754)
|
||||
* [chore] Bump engine.io to version 1.8.0 (#2755)
|
||||
* [chore] Bump socket.io-adapter to version 0.5.0 (#2756)
|
||||
|
||||
1.5.1 / 2016-10-24
|
||||
==================
|
||||
|
||||
* [fix] Avoid swallowing exceptions thrown by user event handlers (#2682)
|
||||
* [test] Use client function to unify `client` in test script (#2731)
|
||||
* [docs] Add link to LICENSE (#2221)
|
||||
* [docs] Fix JSDoc of optional parameters (#2465)
|
||||
* [docs] Fix typo (#2724)
|
||||
* [docs] Link readme npm package badge to npm registry page (#2612)
|
||||
* [docs] Minor fixes (#2526)
|
||||
* [chore] Bump socket.io-parser to 2.3.0 (#2730)
|
||||
* [chore] Add Github issue and PR templates (#2733)
|
||||
* [chore] Bump engine.io to 1.7.2 (#2729)
|
||||
* [chore] Bump socket.io-parser to 2.3.1 (#2734)
|
||||
|
||||
1.5.0 / 2016-10-06
|
||||
==================
|
||||
|
||||
* [feature] stop append /# before id when no namespace (#2508)
|
||||
* [feature] Add a 'disconnecting' event to access to socket.rooms upon disconnection (#2332)
|
||||
* [fix] Fix query string management (#2422)
|
||||
* [fix] add quote to exec paths, prevent error when spaces in path (#2508)
|
||||
* [docs] Prevent mixup for new programmers (#2599)
|
||||
* [example] Fix chat display in Firefox (#2477)
|
||||
* [chore] Add gulp & babel in the build process (#2471)
|
||||
* [chore] Bump engine.io to 1.7.0 (#2707)
|
||||
* [chore] Remove unused zuul-ngrok dependency (#2708)
|
||||
* [chore] Point towards current master of socket.io-client (#2710)
|
||||
* [chore] Restrict files included in npm package (#2709)
|
||||
* [chore] Link build badge to master branch (#2549)
|
||||
|
||||
1.4.8 / 2016-06-23
|
||||
==================
|
||||
|
||||
* package: bump `engine.io`
|
||||
|
||||
1.4.7 / 2016-06-23
|
||||
==================
|
||||
|
||||
* package: bump `engine.io`
|
||||
|
||||
1.4.6 / 2016-05-02
|
||||
==================
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2015 Automattic <dev@cloudup.com>
|
||||
Copyright (c) 2014-2016 Automattic <dev@cloudup.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
11
Makefile
11
Makefile
@@ -1,15 +1,8 @@
|
||||
|
||||
REPORTER = dot
|
||||
|
||||
test:
|
||||
@./node_modules/.bin/mocha \
|
||||
--reporter $(REPORTER) \
|
||||
--slow 200ms \
|
||||
--bail
|
||||
@./node_modules/.bin/gulp test
|
||||
|
||||
test-cov:
|
||||
@./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- \
|
||||
--reporter $(REPORTER) \
|
||||
test/
|
||||
@./node_modules/.bin/gulp test-cov
|
||||
|
||||
.PHONY: test
|
||||
|
||||
118
Readme.md
118
Readme.md
@@ -1,10 +1,10 @@
|
||||
|
||||
# socket.io
|
||||
|
||||
[](https://travis-ci.org/socketio/socket.io)
|
||||
[](https://travis-ci.org/socketio/socket.io)
|
||||
[](https://david-dm.org/socketio/socket.io)
|
||||
[](https://david-dm.org/socketio/socket.io#info=devDependencies)
|
||||

|
||||
[](https://www.npmjs.com/package/socket.io)
|
||||

|
||||
[](http://slack.socket.io)
|
||||
|
||||
@@ -16,9 +16,9 @@ HTTP server listening on port `3000`.
|
||||
```js
|
||||
var server = require('http').createServer();
|
||||
var io = require('socket.io')(server);
|
||||
io.on('connection', function(socket){
|
||||
socket.on('event', function(data){});
|
||||
socket.on('disconnect', function(){});
|
||||
io.on('connection', function(client){
|
||||
client.on('event', function(data){});
|
||||
client.on('disconnect', function(){});
|
||||
});
|
||||
server.listen(3000);
|
||||
```
|
||||
@@ -27,7 +27,7 @@ server.listen(3000);
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){});
|
||||
io.on('connection', function(client){});
|
||||
io.listen(3000);
|
||||
```
|
||||
|
||||
@@ -147,7 +147,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/expressjs/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
|
||||
@@ -183,7 +183,7 @@ server.listen(3000);
|
||||
Initializes and retrieves the given `Namespace` by its pathname
|
||||
identifier `nsp`.
|
||||
|
||||
If the namespace was already initialized it returns it right away.
|
||||
If the namespace was already initialized it returns it immediately.
|
||||
|
||||
### Server#emit
|
||||
|
||||
@@ -198,9 +198,14 @@ server.listen(3000);
|
||||
|
||||
For other available methods, see `Namespace` below.
|
||||
|
||||
### Server#close
|
||||
### Server#close([fn:Function])
|
||||
|
||||
Closes socket server
|
||||
Closes socket.io server.
|
||||
|
||||
The optional `fn` is passed to the `server.close([callback])` method of the
|
||||
core `net` module and is called on error or when all connections are closed.
|
||||
The callback is expected to implement the common single argument `err`
|
||||
signature (if any).
|
||||
|
||||
```js
|
||||
var Server = require('socket.io');
|
||||
@@ -280,7 +285,7 @@ server.listen(3000);
|
||||
### Namespace#use(fn:Function):Namespace
|
||||
|
||||
Registers a middleware, which is a function that gets executed for
|
||||
every incoming `Socket` and receives as parameter the socket and a
|
||||
every incoming `Socket`, and receives as parameters the socket and a
|
||||
function to optionally defer execution to the next registered
|
||||
middleware.
|
||||
|
||||
@@ -300,10 +305,32 @@ server.listen(3000);
|
||||
A `Socket` is the fundamental class for interacting with browser
|
||||
clients. A `Socket` belongs to a certain `Namespace` (by default `/`)
|
||||
and uses an underlying `Client` to communicate.
|
||||
|
||||
It should be noted the `Socket` doesn't relate directly to the actual
|
||||
underlying TCP/IP `socket` and it is only the name of the class.
|
||||
|
||||
### Socket#use(fn:Function):Socket
|
||||
|
||||
Registers a middleware, which is a function that gets executed for
|
||||
every incoming `Packet` and receives as parameter the packet and a
|
||||
function to optionally defer execution to the next registered
|
||||
middleware.
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){
|
||||
socket.use(function(packet, next){
|
||||
if (packet.doge === true) return next();
|
||||
next(new Error('Not a doge error'));
|
||||
});
|
||||
```
|
||||
|
||||
Errors passed to middleware callbacks are sent as special `error`
|
||||
packets to clients.
|
||||
|
||||
### Socket#rooms:Object
|
||||
|
||||
A hash of strings identifying the rooms this socket is in, indexed by
|
||||
A hash of strings identifying the rooms this client is in, indexed by
|
||||
room name.
|
||||
|
||||
### Socket#client:Client
|
||||
@@ -313,7 +340,8 @@ server.listen(3000);
|
||||
### Socket#conn:Socket
|
||||
|
||||
A reference to the underlying `Client` transport connection (engine.io
|
||||
`Socket` object).
|
||||
`Socket` object). This allows access to the IO transport layer, which
|
||||
still (mostly) abstracts the actual TCP/IP socket.
|
||||
|
||||
### Socket#request:Request
|
||||
|
||||
@@ -323,30 +351,30 @@ server.listen(3000);
|
||||
|
||||
### Socket#id:String
|
||||
|
||||
A unique identifier for the socket session, that comes from the
|
||||
A unique identifier for the session, that comes from the
|
||||
underlying `Client`.
|
||||
|
||||
### Socket#emit(name:String[, …]):Socket
|
||||
|
||||
Emits an event to the socket identified by the string `name`. Any
|
||||
other parameters can be included.
|
||||
Emits an event identified by the string `name` to the client.
|
||||
Any other parameters can be included.
|
||||
|
||||
All datastructures are supported, including `Buffer`. JavaScript
|
||||
functions can't be serialized/deserialized.
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){
|
||||
socket.emit('an event', { some: 'data' });
|
||||
io.on('connection', function(client){
|
||||
client.emit('an event', { some: 'data' });
|
||||
});
|
||||
```
|
||||
|
||||
### Socket#join(name:String[, fn:Function]):Socket
|
||||
|
||||
Adds the socket to the `room`, and fires optionally a callback `fn`
|
||||
Adds the client to the `room`, and fires optionally a callback `fn`
|
||||
with `err` signature (if any).
|
||||
|
||||
The socket is automatically a member of a room identified with its
|
||||
The client is automatically a member of a room identified with its
|
||||
session id (see `Socket#id`).
|
||||
|
||||
The mechanics of joining rooms are handled by the `Adapter`
|
||||
@@ -355,7 +383,7 @@ server.listen(3000);
|
||||
|
||||
### Socket#leave(name:String[, fn:Function]):Socket
|
||||
|
||||
Removes the socket from `room`, and fires optionally a callback `fn`
|
||||
Removes the client from `room`, and fires optionally a callback `fn`
|
||||
with `err` signature (if any).
|
||||
|
||||
**Rooms are left automatically upon disconnection**.
|
||||
@@ -367,14 +395,14 @@ server.listen(3000);
|
||||
### Socket#to(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`.
|
||||
only be _broadcasted_ to clients that have joined the given `room`.
|
||||
|
||||
To emit to multiple rooms, you can call `to` several times.
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){
|
||||
socket.to('others').emit('an event', { some: 'data' });
|
||||
io.on('connection', function(client){
|
||||
client.to('others').emit('an event', { some: 'data' });
|
||||
});
|
||||
```
|
||||
|
||||
@@ -389,15 +417,38 @@ server.listen(3000);
|
||||
|
||||
```js
|
||||
var io = require('socket.io')();
|
||||
io.on('connection', function(socket){
|
||||
socket.compress(false).emit('an event', { some: 'data' });
|
||||
io.on('connection', function(client){
|
||||
client.compress(false).emit('an event', { some: 'data' });
|
||||
});
|
||||
```
|
||||
|
||||
### Socket#disconnect(close:Boolean):Socket
|
||||
|
||||
Disconnects this client. If value of close is `true`, closes the underlying connection.
|
||||
Otherwise, it just disconnects the namespace.
|
||||
|
||||
#### Events
|
||||
|
||||
- `disconnect`
|
||||
- Fired upon disconnection.
|
||||
- **Arguments**
|
||||
- `String`: the reason of the disconnection (either client or server-side)
|
||||
- `error`
|
||||
- Fired when an error occurs.
|
||||
- **Arguments**
|
||||
- `Object`: error data
|
||||
- `disconnecting`
|
||||
- Fired when the client is going to be disconnected (but hasn't left its `rooms` yet).
|
||||
- **Arguments**
|
||||
- `String`: the reason of the disconnection (either client or server-side)
|
||||
|
||||
These are reserved events (along with `connect`, `newListener` and `removeListener`) which cannot be used as event names.
|
||||
|
||||
|
||||
### Client
|
||||
|
||||
The `Client` class represents an incoming transport (engine.io)
|
||||
connection. A `Client` can be associated with many multiplexed `Socket`
|
||||
connection. A `Client` can be associated with many multiplexed `Socket`s
|
||||
that belong to different `Namespace`s.
|
||||
|
||||
### Client#conn
|
||||
@@ -422,6 +473,17 @@ To see the output from all of Socket.IO's debugging scopes you can use:
|
||||
DEBUG=socket.io* node myapp
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```
|
||||
npm test
|
||||
```
|
||||
This runs the `gulp` task `test`. By default the test will be run with the source code in `lib` directory.
|
||||
|
||||
Set the environmental variable `TEST_VERSION` to `compat` to test the transpiled es5-compat version of the code.
|
||||
|
||||
The `gulp` task `test` will always transpile the source code into es5 and export to `dist` first before running the test.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
[MIT](LICENSE)
|
||||
|
||||
@@ -10,7 +10,7 @@ $ cd socket.io
|
||||
$ npm install
|
||||
$ cd examples/chat
|
||||
$ npm install
|
||||
$ node .
|
||||
$ npm start
|
||||
```
|
||||
|
||||
And point your browser to `http://localhost:3000`. Optionally, specify
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
"private": true,
|
||||
"license": "BSD",
|
||||
"dependencies": {
|
||||
"express": "3.4.8"
|
||||
"express": "4.13.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,4 +263,20 @@ $(function() {
|
||||
socket.on('stop typing', function (data) {
|
||||
removeChatTyping(data);
|
||||
});
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
log('you have been disconnected');
|
||||
});
|
||||
|
||||
socket.on('reconnect', function () {
|
||||
log('you have been reconnected');
|
||||
if (username) {
|
||||
socket.emit('add user', username);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('reconnect_error', function () {
|
||||
log('attempt to reconnect has failed');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -128,7 +128,6 @@ ul {
|
||||
}
|
||||
|
||||
.username {
|
||||
float: left;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
padding-right: 15px;
|
||||
|
||||
69
gulpfile.js
Normal file
69
gulpfile.js
Normal file
@@ -0,0 +1,69 @@
|
||||
const gulp = require('gulp');
|
||||
const mocha = require('gulp-mocha');
|
||||
const babel = require("gulp-babel");
|
||||
const istanbul = require('gulp-istanbul');
|
||||
const help = require('gulp-task-listing');
|
||||
const del = require('del');
|
||||
|
||||
gulp.task('help', help);
|
||||
|
||||
gulp.task('default', ['transpile']);
|
||||
|
||||
const TRANSPILE_DEST_DIR = './dist';
|
||||
|
||||
// By default, individual js files are transformed by babel and exported to /dist
|
||||
gulp.task('transpile', function () {
|
||||
return gulp.src("lib/*.js")
|
||||
.pipe(babel({ "presets": ["es2015"] }))
|
||||
.pipe(gulp.dest(TRANSPILE_DEST_DIR));
|
||||
});
|
||||
|
||||
gulp.task('clean', function () {
|
||||
return del([TRANSPILE_DEST_DIR]);
|
||||
})
|
||||
|
||||
gulp.task('test', ['transpile'], function(){
|
||||
return gulp.src('test/socket.io.js', {read: false})
|
||||
.pipe(mocha({
|
||||
slow: 200,
|
||||
reporter: 'spec',
|
||||
bail: true,
|
||||
timeout: 10000
|
||||
}))
|
||||
.once('error', function (err) {
|
||||
console.error(err.stack);
|
||||
process.exit(1);
|
||||
})
|
||||
.once('end', function () {
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('set-compat-node-env', function() {
|
||||
process.env.TEST_VERSION = 'compat';
|
||||
});
|
||||
|
||||
gulp.task('test-compat', ['set-compat-node-env', 'test']);
|
||||
|
||||
gulp.task('istanbul-pre-test', function () {
|
||||
return gulp.src(['lib/**/*.js'])
|
||||
// Covering files
|
||||
.pipe(istanbul())
|
||||
// Force `require` to return covered files
|
||||
.pipe(istanbul.hookRequire());
|
||||
});
|
||||
|
||||
gulp.task('test-cov', ['istanbul-pre-test'], function(){
|
||||
return gulp.src('test/socket.io.js', {read: false})
|
||||
.pipe(mocha({
|
||||
reporter: 'dot'
|
||||
}))
|
||||
.pipe(istanbul.writeReports())
|
||||
.once('error', function (err){
|
||||
console.error(err.stack);
|
||||
process.exit(1);
|
||||
})
|
||||
.once('end', function (){
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
var parser = require('socket.io-parser');
|
||||
var debug = require('debug')('socket.io:client');
|
||||
var url = require('url');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
@@ -58,7 +59,7 @@ Client.prototype.setup = function(){
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Client.prototype.connect = function(name){
|
||||
Client.prototype.connect = function(name, query){
|
||||
debug('connecting to namespace %s', name);
|
||||
var nsp = this.server.nsps[name];
|
||||
if (!nsp) {
|
||||
@@ -72,7 +73,7 @@ Client.prototype.connect = function(name){
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var socket = nsp.add(this, function(){
|
||||
var socket = nsp.add(this, query, function(){
|
||||
self.sockets[socket.id] = socket;
|
||||
self.nsps[nsp.name] = socket;
|
||||
|
||||
@@ -186,11 +187,13 @@ Client.prototype.ondata = function(data){
|
||||
|
||||
Client.prototype.ondecoded = function(packet) {
|
||||
if (parser.CONNECT == packet.type) {
|
||||
this.connect(packet.nsp);
|
||||
this.connect(url.parse(packet.nsp).pathname, url.parse(packet.nsp, true).query);
|
||||
} else {
|
||||
var socket = this.nsps[packet.nsp];
|
||||
if (socket) {
|
||||
socket.onpacket(packet);
|
||||
process.nextTick(function() {
|
||||
socket.onpacket(packet);
|
||||
});
|
||||
} else {
|
||||
debug('no socket for namespace %s', packet.nsp);
|
||||
}
|
||||
|
||||
94
lib/index.js
94
lib/index.js
@@ -7,8 +7,9 @@ var http = require('http');
|
||||
var read = require('fs').readFileSync;
|
||||
var engine = require('engine.io');
|
||||
var client = require('socket.io-client');
|
||||
var clientVersion = require('socket.io-client/package').version;
|
||||
var clientVersion = require('socket.io-client/package.json').version;
|
||||
var Client = require('./client');
|
||||
var Emitter = require('events').EventEmitter;
|
||||
var Namespace = require('./namespace');
|
||||
var Adapter = require('socket.io-adapter');
|
||||
var debug = require('debug')('socket.io:server');
|
||||
@@ -24,13 +25,14 @@ module.exports = Server;
|
||||
* Socket.IO client source.
|
||||
*/
|
||||
|
||||
var clientSource = read(require.resolve('socket.io-client/socket.io.js'), 'utf-8');
|
||||
var clientSource = undefined;
|
||||
var clientSourceMap = undefined;
|
||||
|
||||
/**
|
||||
* Server constructor.
|
||||
*
|
||||
* @param {http.Server|Number|Object} srv http server, port or options
|
||||
* @param {Object} opts
|
||||
* @param {Object} [opts]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
@@ -94,6 +96,16 @@ Server.prototype.checkRequest = function(req, fn) {
|
||||
Server.prototype.serveClient = function(v){
|
||||
if (!arguments.length) return this._serveClient;
|
||||
this._serveClient = v;
|
||||
|
||||
if (v && !clientSource) {
|
||||
clientSource = read(require.resolve('socket.io-client/dist/socket.io.min.js'), 'utf-8');
|
||||
try {
|
||||
clientSourceMap = read(require.resolve('socket.io-client/dist/socket.io.js.map'), 'utf-8');
|
||||
} catch(err) {
|
||||
debug('could not load sourcemap file');
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -109,7 +121,7 @@ var oldSettings = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Backwards compatiblity.
|
||||
* Backwards compatibility.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
@@ -249,11 +261,14 @@ Server.prototype.attach = function(srv, opts){
|
||||
Server.prototype.attachServe = function(srv){
|
||||
debug('attaching client serving req handler');
|
||||
var url = this._path + '/socket.io.js';
|
||||
var urlMap = this._path + '/socket.io.js.map';
|
||||
var evs = srv.listeners('request').slice(0);
|
||||
var self = this;
|
||||
srv.removeAllListeners('request');
|
||||
srv.on('request', function(req, res) {
|
||||
if (0 === req.url.indexOf(url)) {
|
||||
if (0 === req.url.indexOf(urlMap)) {
|
||||
self.serveMap(req, res);
|
||||
} else if (0 === req.url.indexOf(url)) {
|
||||
self.serve(req, res);
|
||||
} else {
|
||||
for (var i = 0; i < evs.length; i++) {
|
||||
@@ -272,9 +287,13 @@ Server.prototype.attachServe = function(srv){
|
||||
*/
|
||||
|
||||
Server.prototype.serve = function(req, res){
|
||||
// Per the standard, ETags must be quoted:
|
||||
// https://tools.ietf.org/html/rfc7232#section-2.3
|
||||
var expectedEtag = '"' + clientVersion + '"';
|
||||
|
||||
var etag = req.headers['if-none-match'];
|
||||
if (etag) {
|
||||
if (clientVersion == etag) {
|
||||
if (expectedEtag == etag) {
|
||||
debug('serve client 304');
|
||||
res.writeHead(304);
|
||||
res.end();
|
||||
@@ -284,11 +303,42 @@ Server.prototype.serve = function(req, res){
|
||||
|
||||
debug('serve client source');
|
||||
res.setHeader('Content-Type', 'application/javascript');
|
||||
res.setHeader('ETag', clientVersion);
|
||||
res.setHeader('ETag', expectedEtag);
|
||||
res.setHeader('X-SourceMap', 'socket.io.js.map');
|
||||
res.writeHead(200);
|
||||
res.end(clientSource);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles a request serving `/socket.io.js.map`
|
||||
*
|
||||
* @param {http.Request} req
|
||||
* @param {http.Response} res
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Server.prototype.serveMap = function(req, res){
|
||||
// Per the standard, ETags must be quoted:
|
||||
// https://tools.ietf.org/html/rfc7232#section-2.3
|
||||
var expectedEtag = '"' + clientVersion + '"';
|
||||
|
||||
var etag = req.headers['if-none-match'];
|
||||
if (etag) {
|
||||
if (expectedEtag == etag) {
|
||||
debug('serve client 304');
|
||||
res.writeHead(304);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
debug('serve client sourcemap');
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.setHeader('ETag', expectedEtag);
|
||||
res.writeHead(200);
|
||||
res.end(clientSourceMap);
|
||||
};
|
||||
|
||||
/**
|
||||
* Binds socket.io to an engine.io instance.
|
||||
*
|
||||
@@ -322,7 +372,7 @@ Server.prototype.onconnection = function(conn){
|
||||
* Looks up a namespace.
|
||||
*
|
||||
* @param {String} name nsp name
|
||||
* @param {Function} fn optional, nsp `connection` ev handler
|
||||
* @param {Function} [fn] optional, nsp `connection` ev handler
|
||||
* @api public
|
||||
*/
|
||||
|
||||
@@ -342,10 +392,11 @@ Server.prototype.of = function(name, fn){
|
||||
/**
|
||||
* Closes server connection
|
||||
*
|
||||
* @param {Function} [fn] optional, called as `fn([err])` on error OR all conns closed
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.close = function(){
|
||||
Server.prototype.close = function(fn){
|
||||
for (var id in this.nsps['/'].sockets) {
|
||||
if (this.nsps['/'].sockets.hasOwnProperty(id)) {
|
||||
this.nsps['/'].sockets[id].onclose();
|
||||
@@ -354,8 +405,10 @@ Server.prototype.close = function(){
|
||||
|
||||
this.engine.close();
|
||||
|
||||
if(this.httpServer){
|
||||
this.httpServer.close();
|
||||
if (this.httpServer) {
|
||||
this.httpServer.close(fn);
|
||||
} else {
|
||||
fn && fn();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -363,18 +416,23 @@ Server.prototype.close = function(){
|
||||
* Expose main namespace (/).
|
||||
*/
|
||||
|
||||
['on', 'to', 'in', 'use', 'emit', 'send', 'write', 'clients', 'compress'].forEach(function(fn){
|
||||
var emitterMethods = Object.keys(Emitter.prototype).filter(function(key){
|
||||
return typeof Emitter.prototype[key] === 'function';
|
||||
});
|
||||
|
||||
emitterMethods.concat(['to', 'in', 'use', 'send', 'write', 'clients', 'compress']).forEach(function(fn){
|
||||
Server.prototype[fn] = function(){
|
||||
var nsp = this.sockets[fn];
|
||||
return nsp.apply(this.sockets, arguments);
|
||||
return this.sockets[fn].apply(this.sockets, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
Namespace.flags.forEach(function(flag){
|
||||
Server.prototype.__defineGetter__(flag, function(){
|
||||
this.sockets.flags = this.sockets.flags || {};
|
||||
this.sockets.flags[flag] = true;
|
||||
return this;
|
||||
Object.defineProperty(Server.prototype, flag, {
|
||||
get: function() {
|
||||
this.sockets.flags = this.sockets.flags || {};
|
||||
this.sockets.flags[flag] = true;
|
||||
return this;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ exports.events = [
|
||||
|
||||
exports.flags = [
|
||||
'json',
|
||||
'volatile'
|
||||
'volatile',
|
||||
'local'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -69,10 +70,12 @@ Namespace.prototype.__proto__ = Emitter.prototype;
|
||||
*/
|
||||
|
||||
exports.flags.forEach(function(flag){
|
||||
Namespace.prototype.__defineGetter__(flag, function(){
|
||||
this.flags = this.flags || {};
|
||||
this.flags[flag] = true;
|
||||
return this;
|
||||
Object.defineProperty(Namespace.prototype, flag, {
|
||||
get: function() {
|
||||
this.flags = this.flags || {};
|
||||
this.flags[flag] = true;
|
||||
return this;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -137,7 +140,7 @@ Namespace.prototype.run = function(socket, fn){
|
||||
*/
|
||||
|
||||
Namespace.prototype.to =
|
||||
Namespace.prototype['in'] = function(name){
|
||||
Namespace.prototype.in = function(name){
|
||||
this.rooms = this.rooms || [];
|
||||
if (!~this.rooms.indexOf(name)) this.rooms.push(name);
|
||||
return this;
|
||||
@@ -150,9 +153,9 @@ Namespace.prototype['in'] = function(name){
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Namespace.prototype.add = function(client, fn){
|
||||
Namespace.prototype.add = function(client, query, fn){
|
||||
debug('adding socket to nsp %s', this.name);
|
||||
var socket = new Socket(this, client);
|
||||
var socket = new Socket(this, client, query);
|
||||
var self = this;
|
||||
this.run(socket, function(err){
|
||||
process.nextTick(function(){
|
||||
|
||||
102
lib/socket.js
102
lib/socket.js
@@ -8,6 +8,7 @@ var parser = require('socket.io-parser');
|
||||
var url = require('url');
|
||||
var debug = require('debug')('socket.io:socket');
|
||||
var hasBin = require('has-binary');
|
||||
var assign = require('object-assign');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
@@ -25,6 +26,7 @@ exports.events = [
|
||||
'error',
|
||||
'connect',
|
||||
'disconnect',
|
||||
'disconnecting',
|
||||
'newListener',
|
||||
'removeListener'
|
||||
];
|
||||
@@ -55,18 +57,19 @@ var emit = Emitter.prototype.emit;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Socket(nsp, client){
|
||||
function Socket(nsp, client, query){
|
||||
this.nsp = nsp;
|
||||
this.server = nsp.server;
|
||||
this.adapter = this.nsp.adapter;
|
||||
this.id = nsp.name + '#' + client.id;
|
||||
this.id = nsp.name !== '/' ? nsp.name + '#' + client.id : client.id;
|
||||
this.client = client;
|
||||
this.conn = client.conn;
|
||||
this.rooms = {};
|
||||
this.acks = {};
|
||||
this.connected = true;
|
||||
this.disconnected = false;
|
||||
this.handshake = this.buildHandshake();
|
||||
this.handshake = this.buildHandshake(query);
|
||||
this.fns = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,10 +83,12 @@ Socket.prototype.__proto__ = Emitter.prototype;
|
||||
*/
|
||||
|
||||
flags.forEach(function(flag){
|
||||
Socket.prototype.__defineGetter__(flag, function(){
|
||||
this.flags = this.flags || {};
|
||||
this.flags[flag] = true;
|
||||
return this;
|
||||
Object.defineProperty(Socket.prototype, flag, {
|
||||
get: function() {
|
||||
this.flags = this.flags || {};
|
||||
this.flags[flag] = true;
|
||||
return this;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -93,8 +98,10 @@ flags.forEach(function(flag){
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.__defineGetter__('request', function(){
|
||||
return this.conn.request;
|
||||
Object.defineProperty(Socket.prototype, 'request', {
|
||||
get: function() {
|
||||
return this.conn.request;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -103,7 +110,13 @@ Socket.prototype.__defineGetter__('request', function(){
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.buildHandshake = function(){
|
||||
Socket.prototype.buildHandshake = function(query){
|
||||
var self = this;
|
||||
function buildQuery(){
|
||||
var requestQuery = url.parse(self.request.url, true).query;
|
||||
//if socket-specific query exist, replace query strings in requestQuery
|
||||
return assign({}, query, requestQuery);
|
||||
}
|
||||
return {
|
||||
headers: this.request.headers,
|
||||
time: (new Date) + '',
|
||||
@@ -112,7 +125,7 @@ Socket.prototype.buildHandshake = function(){
|
||||
secure: !!this.request.connection.encrypted,
|
||||
issued: +(new Date),
|
||||
url: this.request.url,
|
||||
query: url.parse(this.request.url, true).query || {}
|
||||
query: buildQuery()
|
||||
};
|
||||
};
|
||||
|
||||
@@ -268,8 +281,10 @@ Socket.prototype.leaveAll = function(){
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by `Namespace` upon succesful
|
||||
* Called by `Namespace` upon successful
|
||||
* middleware execution (ie: authorization).
|
||||
* Socket is added to namespace array before
|
||||
* call to join, so adapters can access it.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
@@ -332,7 +347,7 @@ Socket.prototype.onevent = function(packet){
|
||||
args.push(this.ack(packet.id));
|
||||
}
|
||||
|
||||
emit.apply(this, args);
|
||||
this.dispatch(args);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -416,6 +431,7 @@ Socket.prototype.onerror = function(err){
|
||||
Socket.prototype.onclose = function(reason){
|
||||
if (!this.connected) return this;
|
||||
debug('closing socket - reason %s', reason);
|
||||
this.emit('disconnecting', reason);
|
||||
this.leaveAll();
|
||||
this.nsp.remove(this);
|
||||
this.client.remove(this);
|
||||
@@ -468,3 +484,63 @@ Socket.prototype.compress = function(compress){
|
||||
this.flags.compress = compress;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch incoming event to socket listeners.
|
||||
*
|
||||
* @param {Array} event that will get emitted
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.dispatch = function(event){
|
||||
debug('dispatching an event %j', event);
|
||||
var self = this;
|
||||
this.run(event, function(err){
|
||||
process.nextTick(function(){
|
||||
if (err) {
|
||||
return self.error(err.data || err.message);
|
||||
}
|
||||
emit.apply(self, event);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up socket middleware.
|
||||
*
|
||||
* @param {Function} middleware function (event, next)
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.use = function(fn){
|
||||
this.fns.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the middleware for an incoming event.
|
||||
*
|
||||
* @param {Array} event that will get emitted
|
||||
* @param {Function} last fn call in the middleware
|
||||
* @api private
|
||||
*/
|
||||
Socket.prototype.run = function(event, fn){
|
||||
var fns = this.fns.slice(0);
|
||||
if (!fns.length) return fn(null);
|
||||
|
||||
function run(i){
|
||||
fns[i](event, function(err){
|
||||
// upon error, short-circuit
|
||||
if (err) return fn(err);
|
||||
|
||||
// if no middleware left, summon callback
|
||||
if (!fns[i + 1]) return fn(null);
|
||||
|
||||
// go on to next
|
||||
run(i + 1);
|
||||
});
|
||||
}
|
||||
|
||||
run(0);
|
||||
};
|
||||
|
||||
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "socket.io",
|
||||
"version": "1.4.6",
|
||||
"version": "1.7.4",
|
||||
"description": "node.js realtime framework server",
|
||||
"keywords": [
|
||||
"realtime",
|
||||
@@ -12,29 +12,39 @@
|
||||
"io"
|
||||
],
|
||||
"main": "./lib/index",
|
||||
"files": [
|
||||
"lib/"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Automattic/socket.io"
|
||||
"url": "git://github.com/socketio/socket.io"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --reporter dot --slow 200ms --bail"
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"engine.io": "1.6.9",
|
||||
"socket.io-parser": "2.2.6",
|
||||
"socket.io-client": "1.4.6",
|
||||
"socket.io-adapter": "0.4.0",
|
||||
"debug": "2.3.3",
|
||||
"engine.io": "~1.8.4",
|
||||
"has-binary": "0.1.7",
|
||||
"debug": "2.2.0"
|
||||
"object-assign": "4.1.0",
|
||||
"socket.io-adapter": "0.5.0",
|
||||
"socket.io-client": "1.7.4",
|
||||
"socket.io-parser": "2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "6.3.13",
|
||||
"del": "2.2.0",
|
||||
"expect.js": "0.3.1",
|
||||
"gulp": "3.9.0",
|
||||
"gulp-babel": "6.1.1",
|
||||
"gulp-istanbul": "0.10.3",
|
||||
"gulp-mocha": "2.2.0",
|
||||
"gulp-task-listing": "1.0.1",
|
||||
"istanbul": "0.4.1",
|
||||
"mocha": "2.3.4",
|
||||
"superagent": "1.6.1",
|
||||
"supertest": "1.1.0",
|
||||
"zuul-ngrok": "3.2.0"
|
||||
"supertest": "1.1.0"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
|
||||
var testVersion = process.env.TEST_VERSION;
|
||||
var http = require('http').Server;
|
||||
var io = require('..');
|
||||
var io;
|
||||
if (testVersion === 'compat') {
|
||||
console.log('testing compat version');
|
||||
io = require('../dist');
|
||||
} else {
|
||||
io = require('../lib');
|
||||
}
|
||||
var fs = require('fs');
|
||||
var join = require('path').join;
|
||||
var exec = require('child_process').exec;
|
||||
@@ -161,7 +167,7 @@ describe('socket.io', function(){
|
||||
if (err) return done(err);
|
||||
var ctype = res.headers['content-type'];
|
||||
expect(ctype).to.be('application/javascript');
|
||||
expect(res.headers.etag).to.be(clientVersion);
|
||||
expect(res.headers.etag).to.be('"' + clientVersion + '"');
|
||||
expect(res.text).to.match(/engine\.io/);
|
||||
expect(res.status).to.be(200);
|
||||
done();
|
||||
@@ -173,7 +179,7 @@ describe('socket.io', function(){
|
||||
io(srv);
|
||||
request(srv)
|
||||
.get('/socket.io/socket.io.js')
|
||||
.set('If-None-Match', clientVersion)
|
||||
.set('If-None-Match', '"' + clientVersion + '"')
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
expect(res.statusCode).to.be(304);
|
||||
@@ -393,7 +399,7 @@ describe('socket.io', function(){
|
||||
var net = require('net');
|
||||
var server = net.createServer();
|
||||
|
||||
var clientSocket = ioc('ws://0.0.0.0:' + PORT);
|
||||
var clientSocket = ioc('ws://0.0.0.0:' + PORT, { reconnection: false });
|
||||
|
||||
clientSocket.on('disconnect', function init() {
|
||||
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);
|
||||
@@ -415,8 +421,8 @@ describe('socket.io', function(){
|
||||
|
||||
describe('graceful close', function(){
|
||||
function fixture(filename) {
|
||||
return process.execPath + ' ' +
|
||||
join(__dirname, 'fixtures', filename);
|
||||
return '"' + process.execPath + '" "' +
|
||||
join(__dirname, 'fixtures', filename) + '"';
|
||||
}
|
||||
|
||||
it('should stop socket and timers', function(done){
|
||||
@@ -426,9 +432,18 @@ describe('socket.io', function(){
|
||||
});
|
||||
|
||||
describe('namespaces', function(){
|
||||
var Socket = require('../lib/socket');
|
||||
var Namespace = require('../lib/namespace');
|
||||
|
||||
var Socket;
|
||||
if (testVersion === 'compat') {
|
||||
Socket = require('../dist/socket');
|
||||
} else {
|
||||
Socket = require('../lib/socket');
|
||||
}
|
||||
var Namespace;
|
||||
if (testVersion === 'compat') {
|
||||
Namespace = require('../dist/namespace');
|
||||
} else {
|
||||
Namespace = require('../lib/namespace');
|
||||
}
|
||||
it('should be accessible through .sockets', function(){
|
||||
var sio = io();
|
||||
expect(sio.sockets).to.be.a(Namespace);
|
||||
@@ -629,6 +644,31 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should fire a `disconnecting` event just before leaving all 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(){
|
||||
s.disconnect();
|
||||
});
|
||||
|
||||
var total = 2;
|
||||
s.on('disconnecting', function(reason){
|
||||
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
|
||||
total--;
|
||||
});
|
||||
|
||||
s.on('disconnect', function(reason){
|
||||
expect(Object.keys(s.rooms)).to.eql([]);
|
||||
--total || done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should return error connecting to non-existent namespace', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
@@ -651,7 +691,7 @@ describe('socket.io', function(){
|
||||
var clientSocket2 = client(srv);
|
||||
sio.on('connection', function() {
|
||||
connections++;
|
||||
if(connections === 2) {
|
||||
if (connections === 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -785,7 +825,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
sio.of('/chat').emit('ev', 'data');
|
||||
sio.of('/chat').volatile.emit('ev', 'data');
|
||||
}, 20);
|
||||
}, 50);
|
||||
});
|
||||
|
||||
var socket = client(srv, '/chat');
|
||||
@@ -797,7 +837,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
expect(counter).to.be(1);
|
||||
done();
|
||||
}, 200);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('should emit volatile event', function(done) {
|
||||
@@ -810,7 +850,7 @@ describe('socket.io', function(){
|
||||
// Wait to make sure there are no packets being sent for opening the connection
|
||||
setTimeout(function() {
|
||||
sio.of('/chat').volatile.emit('ev', 'data');
|
||||
}, 20);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
var socket = client(srv, '/chat');
|
||||
@@ -822,7 +862,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
expect(counter).to.be(1);
|
||||
done();
|
||||
}, 200);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('should enable compression by default', function(done){
|
||||
@@ -1139,7 +1179,7 @@ describe('socket.io', function(){
|
||||
// Wait to make sure there are no packets being sent for opening the connection
|
||||
setTimeout(function() {
|
||||
s.volatile.emit('ev', 'data');
|
||||
}, 20);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
var socket = client(srv, { transports: ['polling'] });
|
||||
@@ -1151,7 +1191,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
expect(counter).to.be(1);
|
||||
done();
|
||||
}, 200);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('should emit volatile event (ws)', function(done) {
|
||||
@@ -1190,7 +1230,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
s.volatile.emit('ev', 'data');
|
||||
s.volatile.emit('ev', 'data');
|
||||
}, 20);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
var socket = client(srv, { transports: ['polling'] });
|
||||
@@ -1202,7 +1242,7 @@ describe('socket.io', function(){
|
||||
setTimeout(function() {
|
||||
expect(counter).to.be(1);
|
||||
done();
|
||||
}, 200);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('should emit only one consecutive volatile event (ws)', function(done) {
|
||||
@@ -1506,9 +1546,7 @@ describe('socket.io', function(){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
srv.listen(function() {
|
||||
var addr = srv.listen().address();
|
||||
var url = 'ws://localhost:' + addr.port + '?key1=1&key2=2';
|
||||
var socket = ioc(url);
|
||||
var socket = client(srv, {query: {key1: 1, key2: 2}});
|
||||
sio.on('connection', function(s) {
|
||||
var parsed = require('url').parse(s.request.url);
|
||||
var query = require('querystring').parse(parsed.query);
|
||||
@@ -1518,6 +1556,22 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should see query parameters sent from secondary namespace connections in handshake object', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var client1 = client(srv);
|
||||
var client2 = client(srv, '/connection2', {query: {key1: 'aa', key2: '&=bb'}});
|
||||
sio.on('connection', function(s){
|
||||
});
|
||||
sio.of('/connection2').on('connection', function(s){
|
||||
expect(s.handshake.query.key1).to.be('aa');
|
||||
expect(s.handshake.query.key2).to.be('&=bb');
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
it('should handle very large json', function(done){
|
||||
this.timeout(30000);
|
||||
@@ -1589,11 +1643,10 @@ describe('socket.io', function(){
|
||||
var clientSocket = client(srv, { reconnectionAttempts: 10, reconnectionDelay: 100 });
|
||||
clientSocket.once('connect', function(){
|
||||
srv.close(function(){
|
||||
srv.listen(port, function(){
|
||||
clientSocket.on('reconnect', function(){
|
||||
clientSocket.emit('ev', 'payload');
|
||||
});
|
||||
clientSocket.on('reconnect', function(){
|
||||
clientSocket.emit('ev', 'payload');
|
||||
});
|
||||
sio.listen(port);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2036,7 +2089,12 @@ describe('socket.io', function(){
|
||||
});
|
||||
|
||||
describe('middleware', function(done){
|
||||
var Socket = require('../lib/socket');
|
||||
var Socket;
|
||||
if (testVersion === 'compat') {
|
||||
Socket = require('../dist/socket');
|
||||
} else {
|
||||
Socket = require('../lib/socket');
|
||||
}
|
||||
|
||||
it('should call functions', function(done){
|
||||
var srv = http();
|
||||
@@ -2174,4 +2232,97 @@ describe('socket.io', function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('socket middleware', function(done){
|
||||
var Socket = require('../lib/socket');
|
||||
|
||||
it('should call functions', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
var run = 0;
|
||||
|
||||
srv.listen(function(){
|
||||
var socket = client(srv, { multiplex: false });
|
||||
|
||||
socket.emit('join', 'woot');
|
||||
|
||||
sio.on('connection', function(socket){
|
||||
socket.use(function(event, next){
|
||||
expect(event).to.eql(['join', 'woot']);
|
||||
event.unshift('wrap');
|
||||
run++;
|
||||
next();
|
||||
});
|
||||
socket.use(function(event, next){
|
||||
expect(event).to.eql(['wrap', 'join', 'woot']);
|
||||
run++;
|
||||
next();
|
||||
});
|
||||
socket.on('wrap', function(data1, data2){
|
||||
expect(data1).to.be('join');
|
||||
expect(data2).to.be('woot');
|
||||
expect(run).to.be(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass errors', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
|
||||
srv.listen(function(){
|
||||
var clientSocket = client(srv, { multiplex: false });
|
||||
|
||||
clientSocket.emit('join', 'woot');
|
||||
|
||||
clientSocket.on('error', function(err){
|
||||
expect(err).to.be('Authentication error');
|
||||
done();
|
||||
});
|
||||
|
||||
sio.on('connection', function(socket){
|
||||
socket.use(function(event, next){
|
||||
next(new Error('Authentication error'));
|
||||
});
|
||||
socket.use(function(event, next){
|
||||
done(new Error('nope'));
|
||||
});
|
||||
|
||||
socket.on('join', function(){
|
||||
done(new Error('nope'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass `data` of error object', function(done){
|
||||
var srv = http();
|
||||
var sio = io(srv);
|
||||
|
||||
srv.listen(function(){
|
||||
var clientSocket = client(srv, { multiplex: false });
|
||||
|
||||
clientSocket.emit('join', 'woot');
|
||||
|
||||
clientSocket.on('error', function(err){
|
||||
expect(err).to.eql({ a: 'b', c: 3 });
|
||||
done();
|
||||
});
|
||||
|
||||
sio.on('connection', function(socket){
|
||||
socket.use(function(event, next){
|
||||
var err = new Error('Authentication error');
|
||||
err.data = { a: 'b', c: 3 };
|
||||
next(err);
|
||||
});
|
||||
|
||||
socket.on('join', function(){
|
||||
done(new Error('nope'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user