Compare commits

...

30 Commits

Author SHA1 Message Date
Guillermo Rauch
7ca0606670 Release 0.6.17 2011-03-30 11:45:06 -07:00
Guillermo Rauch
f6036007fc Merge branch 'master' of github.com:LearnBoost/Socket.IO-node 2011-03-30 11:43:23 -07:00
Guillermo Rauch
aa027ab571 Preparing awesome 0.7 changelog 2011-03-07 10:16:51 -08:00
Guillermo Rauch
b4f24c6995 Added reconnect events to chat example 2011-03-07 10:11:24 -08:00
Guillermo Rauch
3a53c63778 Added Arnout as official contributor 2011-03-07 09:46:12 -08:00
Arnout Kazemier
d8e3ccc637 Cleaned up the code, changed tabs to spaces and incorporated feedback on from the pull request 2011-03-06 15:25:35 +01:00
Arnout Kazemier
cef5fb3574 Merge branch 'master' of git://github.com/LearnBoost/Socket.IO-node 2011-03-05 19:36:42 +01:00
Guillermo Rauch
cfbae2ac15 Release 0.6.16 2011-03-04 09:06:01 -08:00
Guillermo Rauch
1072add73f Merge branch 'master' of https://github.com/tifroz/Socket.IO-node into tifroz-master 2011-03-04 09:03:43 -08:00
Arnout Kazemier
648b1d0792 Passes test-cases again, without hanging the test suite.
The fix for it is not as elegant as I would have hoped but it does the
job, preventing un-needed listeners to be added on the connections.
2011-03-03 21:39:27 +01:00
Arnout Kazemier
63624e5996 Added more listeners, to prevent uncaught exceptions. See https://gist.github.com/615009 for uncaptured 'timeout' errors. 2011-03-03 14:13:19 +01:00
Arnout Kazemier
1ee5285136 Fixed the 'possible EventEmitter memory leak detected' bug for the XHR transport. 2011-03-03 13:36:06 +01:00
Guillermo Rauch
5308452b8a Release 0.6.15 2011-02-23 11:20:33 -08:00
mlinnell
2ee09436ce Setting WebSocket buffer to empty once nonce is received (intended to include in previous commit) 2011-02-23 19:01:35 +00:00
mlinnell
d2ecaff462 Fixed memory leak in WebSocket transport.
The WebSocket.buffer would continue to grow, unabated, for each new message.
This buffer is now only utilized to process the nonce, and is set to empty (and no longer filled) once nonce has been received.
Parser instance appears to handle all message buffering, instead of WebSocket entity.
2011-02-23 18:55:24 +00:00
Guillermo Rauch
023566e03b Release 0.6.14 2011-02-22 11:09:42 -08:00
Shripad K
c306a3c303 fixed minor bug in xhr-polling, xhr-multipart, htmlfile. (this.listener.options.log -> self.listener.options.log) 2011-02-22 17:34:39 +05:30
Guillermo Rauch
80f1d9780b Release 0.6.13 2011-02-18 15:18:46 -08:00
Guillermo Rauch
ff10eeecba Fixed references to listener when logging 2011-02-18 15:18:10 -08:00
Guillermo Rauch
cd9cbb500b Fixed listener reference 2011-02-18 15:17:14 -08:00
Guillermo Rauch
de8d573948 Release 0.6.12 2011-02-18 10:36:13 -08:00
Guillermo Rauch
ea9e5ed2cc Fixed noDelay missing file descriptor problem 2011-02-18 10:34:51 -08:00
tifroz
d648fc5a72 Allow x-domain xhr-polling with Origin: null for Chrome/Safari 2011-02-16 00:16:41 -08:00
Guillermo Rauch
109a59ca9a Release 0.6.11 2011-02-15 15:43:35 -08:00
Guillermo Rauch
d304ce19d1 Fixed; Make sure to not execute any other connection operations after WebSocket write error 2011-02-15 15:41:45 -08:00
Marcus Westin
f534a260b3 Don't let errors in an application's message handling code get silently swallowed by any of the transports 2011-02-14 19:56:20 -05:00
Marcus Westin
cff4669d57 Log errors from closing the flash socket server 2011-02-14 19:54:00 -05:00
Guillermo Rauch
4b0a1f22c8 Release 0.6.10 2011-02-09 18:45:00 -08:00
Guillermo Rauch
e79bdb00e9 Added SSL chat example (make example-ssl) 2011-02-09 18:44:07 -08:00
Guillermo Rauch
d11ca00b49 Fixed; possible write errors when a connection error event fires 2011-02-09 18:41:13 -08:00
15 changed files with 300 additions and 49 deletions

View File

@@ -1,4 +1,48 @@
0.6.17 / 2011-03-30
==================
* Fixed the 'possible EventEmitter memory leak detected' bug for the XHR transport
* Reconnection support added to chat example. [3rd-Eden]
0.6.16 / 2011-03-04
===================
* Fixed cross domain xhr-polling in Safari [tifroz]
0.6.15 / 2011-02-23
===================
* Fixed memory leak in WebSocket transport [belorion]
0.6.14 / 2011-02-18
===================
* Fixed logging scope issue [shripad]
0.6.13 / 2011-02-18
===================
* Fixed references to listener when logging
0.6.12 / 2011-02-18
===================
* Fixed noDelay missing file descriptor problem
0.6.11 / 2011-02-15
===================
* Fixed; Make sure to not execute any other connection operations after WebSocket
write error.
* Added more error logging
0.6.10 / 2011-02-09
===================
* Added SSL chat example (`make example-ssl`)
* Fixed; possible write errors when a connection error event fires
0.6.9 / 2011-02-06
==================

View File

@@ -7,4 +7,7 @@ test-cov:
example:
node ./example/server.js
.PHONY: example
example-ssl:
node ./example/server-ssl.js
.PHONY: example

21
example/cert.crt Normal file
View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAMUSOvlaeyQHMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTAxMTE2MDkzMjQ5WhcNMTMxMTE1MDkzMjQ5WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAz+LXZOjcQCJq3+ZKUFabj71oo/ex/XsBcFqtBThjjTw9CVEVwfPQQp4X
wtPiB204vnYXwQ1/R2NdTQqCZu47l79LssL/u2a5Y9+0NEU3nQA5qdt+1FAE0c5o
exPimXOrR3GWfKz7PmZ2O0117IeCUUXPG5U8umhDe/4mDF4ZNJiKc404WthquTqg
S7rLQZHhZ6D0EnGnOkzlmxJMYPNHSOY1/6ivdNUUcC87awNEA3lgfhy25IyBK3QJ
c+aYKNTbt70Lery3bu2wWLFGtmNiGlQTS4JsxImRsECTI727ObS7/FWAQsqW+COL
0Sa5BuMFrFIpjPrEe0ih7vRRbdmXRwIDAQABo1AwTjAdBgNVHQ4EFgQUDnV4d6mD
tOnluLoCjkUHTX/n4agwHwYDVR0jBBgwFoAUDnV4d6mDtOnluLoCjkUHTX/n4agw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAFwV4MQfTo+qMv9JMiyno
IEiqfOz4RgtmBqRnXUffcjS2dhc7/z+FPZnM79Kej8eLHoVfxCyWRHFlzm93vEdv
wxOCrD13EDOi08OOZfxWyIlCa6Bg8cMAKqQzd2OvQOWqlRWBTThBJIhWflU33izX
Qn5GdmYqhfpc+9ZHHGhvXNydtRQkdxVK2dZNzLBvBlLlRmtoClU7xm3A+/5dddeP
AQHEPtyFlUw49VYtZ3ru6KqPms7MKvcRhYLsy9rwSfuuniMlx4d0bDR7TOkw0QQS
A0N8MGQRQpzl4mw4jLzyM5d5QtuGBh2P6hPGa0YQxtI3RPT/p6ENzzBiAKXiSfzo
xw==
-----END CERTIFICATE-----

61
example/chat-ssl.html Normal file
View File

@@ -0,0 +1,61 @@
<!doctype html>
<html>
<head>
<title>socket.io client test</title>
<script src="/json.js"></script> <!-- for ie -->
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
function message(obj){
var el = document.createElement('p');
if ('announcement' in obj) el.innerHTML = '<em>' + esc(obj.announcement) + '</em>';
else if ('message' in obj) el.innerHTML = '<b>' + esc(obj.message[0]) + ':</b> ' + esc(obj.message[1]);
document.getElementById('chat').appendChild(el);
document.getElementById('chat').scrollTop = 1000000;
}
function send(){
var val = document.getElementById('text').value;
socket.send(val);
message({ message: ['you', val] });
document.getElementById('text').value = '';
}
function esc(msg){
return msg.replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
var socket = new io.Socket(null, {port: 443, secure: true, rememberTransport: false});
socket.connect();
socket.on('message', function(obj){
if ('buffer' in obj){
document.getElementById('form').style.display='block';
document.getElementById('chat').innerHTML = '';
for (var i in obj.buffer) message(obj.buffer[i]);
} else message(obj);
});
</script>
<h1>Sample chat client</h1>
<div id="chat"><p>Connecting...</p></div>
<form id="form" onsubmit="send(); return false">
<input type="text" autocomplete="off" id="text"><input type="submit" value="Send">
</form>
<style>
#chat { height: 300px; overflow: auto; width: 800px; border: 1px solid #eee; font: 13px Helvetica, Arial; }
#chat p { padding: 8px; margin: 0; }
#chat p:nth-child(odd) { background: #F6F6F6; }
#form { width: 782px; background: #333; padding: 5px 10px; display: none; }
#form input[type=text] { width: 700px; padding: 5px; background: #fff; border: 1px solid #fff; }
#form input[type=submit] { cursor: pointer; background: #999; border: none; padding: 6px 8px; -moz-border-radius: 8px; -webkit-border-radius: 8px; margin-left: 5px; text-shadow: 0 1px 0 #fff; }
#form input[type=submit]:hover { background: #A2A2A2; }
#form input[type=submit]:active { position: relative; top: 2px; }
</style>
</body>
</html>

View File

@@ -13,6 +13,8 @@
var el = document.createElement('p');
if ('announcement' in obj) el.innerHTML = '<em>' + esc(obj.announcement) + '</em>';
else if ('message' in obj) el.innerHTML = '<b>' + esc(obj.message[0]) + ':</b> ' + esc(obj.message[1]);
if( obj.message && window.console && console.log ) console.log(obj.message[0], obj.message[1]);
document.getElementById('chat').appendChild(el);
document.getElementById('chat').scrollTop = 1000000;
}
@@ -38,11 +40,17 @@
for (var i in obj.buffer) message(obj.buffer[i]);
} else message(obj);
});
socket.on('connect', function(){ message({ message: ['System', 'Connected']})});
socket.on('disconnect', function(){ message({ message: ['System', 'Disconnected']})});
socket.on('reconnect', function(){ message({ message: ['System', 'Reconnected to server']})});
socket.on('reconnecting', function( nextRetry ){ message({ message: ['System', 'Attempting to re-connect to the server, next attempt in ' + nextRetry + 'ms']})});
socket.on('reconnect_failed', function(){ message({ message: ['System', 'Reconnected to server FAILED.']})});
</script>
<h1>Sample chat client</h1>
<div id="chat"><p>Connecting...</p></div>
<form id="form" onsubmit="send(); return false">
<form id="form" onSubmit="send(); return false">
<input type="text" autocomplete="off" id="text"><input type="submit" value="Send">
</form>

27
example/key.key Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAz+LXZOjcQCJq3+ZKUFabj71oo/ex/XsBcFqtBThjjTw9CVEV
wfPQQp4XwtPiB204vnYXwQ1/R2NdTQqCZu47l79LssL/u2a5Y9+0NEU3nQA5qdt+
1FAE0c5oexPimXOrR3GWfKz7PmZ2O0117IeCUUXPG5U8umhDe/4mDF4ZNJiKc404
WthquTqgS7rLQZHhZ6D0EnGnOkzlmxJMYPNHSOY1/6ivdNUUcC87awNEA3lgfhy2
5IyBK3QJc+aYKNTbt70Lery3bu2wWLFGtmNiGlQTS4JsxImRsECTI727ObS7/FWA
QsqW+COL0Sa5BuMFrFIpjPrEe0ih7vRRbdmXRwIDAQABAoIBAGe4+9VqZfJN+dsq
8Osyuz01uQ8OmC0sAWTIqUlQgENIyf9rCJsUBlYmwR5BT6Z69XP6QhHdpSK+TiAR
XUz0EqG9HYzcxHIBaACP7j6iRoQ8R4kbbiWKo0z3WqQGIOqFjvD/mKEuQdE5mEYw
eOUCG6BnX1WY2Yr8WKd2AA/tp0/Y4d8z04u9eodMpSTbHTzYMJb5SbBN1vo6FY7q
8zSuO0BMzXlAxUsCwHsk1GQHFr8Oh3zIR7bQGtMBouI+6Lhh7sjFYsfxJboqMTBV
IKaA216M6ggHG7MU1/jeKcMGDmEfqQLQoyWp29rMK6TklUgipME2L3UD7vTyAVzz
xbVOpZkCgYEA8CXW4sZBBrSSrLR5SB+Ubu9qNTggLowOsC/kVKB2WJ4+xooc5HQo
mFhq1v/WxPQoWIxdYsfg2odlL+JclK5Qcy6vXmRSdAQ5lK9gBDKxZSYc3NwAw2HA
zyHCTK+I0n8PBYQ+yGcrxu0WqTGnlLW+Otk4CejO34WlgHwbH9bbY5UCgYEA3ZvT
C4+OoMHXlmICSt29zUrYiL33IWsR3/MaONxTEDuvgkOSXXQOl/8Ebd6Nu+3WbsSN
bjiPC/JyL1YCVmijdvFpl4gjtgvfJifs4G+QHvO6YfsYoVANk4u6g6rUuBIOwNK4
RwYxwDc0oysp+g7tPxoSgDHReEVKJNzGBe9NGGsCgYEA4O4QP4gCEA3B9BF2J5+s
n9uPVxmiyvZUK6Iv8zP4pThTBBMIzNIf09G9AHPQ7djikU2nioY8jXKTzC3xGTHM
GJZ5m6fLsu7iH+nDvSreDSeNkTBfZqGAvoGYQ8uGE+L+ZuRfCcXYsxIOT5s6o4c3
Dle2rVFpsuKzCY00urW796ECgYBn3go75+xEwrYGQSer6WR1nTgCV29GVYXKPooy
zmmMOT1Yw80NSkEw0pFD4cTyqVYREsTrPU0mn1sPfrOXxnGfZSVFpcR/Je9QVfQ7
eW7GYxwfom335aqHVj10SxRqteP+UoWWnHujCPz94VRKZMakBddYCIGSan+G6YdS
7sdmwwKBgBc2qj0wvGXDF2kCLwSGfWoMf8CS1+5fIiUIdT1e/+7MfDdbmLMIFVjF
QKS3zVViXCbrG5SY6wS9hxoc57f6E2A8vcaX6zy2xkZlGHQCpWRtEM5R01OWJQaH
HsHMmQZGUQVoDm1oRkDhrTFK4K3ukc3rAxzeTZ96utOQN8/KJsTv
-----END RSA PRIVATE KEY-----

66
example/server-ssl.js Normal file
View File

@@ -0,0 +1,66 @@
/**
* Important note: this application is not suitable for benchmarks!
*/
var https = require('https')
, url = require('url')
, fs = require('fs')
, io = require('../')
, sys = require(process.binding('natives').util ? 'util' : 'sys')
, server;
server = https.createServer({
key: fs.readFileSync(__dirname + '/key.key')
, cert: fs.readFileSync(__dirname + '/cert.crt')
}, function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
switch (path){
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Welcome. Try the <a href="/chat-ssl.html">SSL Chat</a> example.</h1>');
res.end();
break;
case '/json.js':
case '/chat-ssl.html':
fs.readFile(__dirname + path, function(err, data){
if (err) return send404(res);
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'})
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(443);
// socket.io, I choose you
// simplest chat application evar
var io = io.listen(server)
, buffer = [];
io.on('connection', function(client){
client.send({ buffer: buffer });
client.broadcast({ announcement: client.sessionId + ' connected' });
client.on('message', function(message){
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.broadcast(msg);
});
client.on('disconnect', function(){
client.broadcast({ announcement: client.sessionId + ' disconnected' });
});
});

View File

@@ -61,33 +61,44 @@ Client.prototype._onMessage = function(data){
};
Client.prototype._onConnect = function(req, res){
var self = this;
var self = this
, attachConnection = !this.connection;
this.request = req;
this.response = res;
this.connection = req.connection;
this.connection.addListener('end', function(){
self._onClose();
if (self.connection)
self.connection.destroy();
});
if(!attachConnection) attachConnection = !attachConnection && this.connection.eventsAttached === undefined;
this.connection.eventsAttached = true;
if (attachConnection){
function destroyConnection(){
self._onClose();
self.connection && self.connection.destroy()
};
this.connection.addListener('end', destroyConnection);
this.connection.addListener('timeout', destroyConnection);
this.connection.addListener('error', destroyConnection);
}
if (req){
req.addListener('error', function(err){
req.end && req.end() || req.destroy && req.destroy();
});
if (res) res.addListener('error', function(err){
res.end && res.end() || res.destroy && res.destroy();
});
req.connection.addListener('error', function(err){
req.connection.end && req.connection.end() || req.connection.destroy && req.connection.destroy();
});
function destroyRequest(){
req.destroy && req.destroy();
};
req.addListener('error', destroyRequest);
req.addListener('timeout', destroyRequest);
if (res){
function destroyResponse(){
res.destroy && res.destroy();
}
res.addListener('error', destroyResponse);
res.addListener('timeout', destroyResponse);
}
if (this._disconnectTimeout) clearTimeout(this._disconnectTimeout);
}
};
Client.prototype._payload = function(){
var payload = [];

View File

@@ -23,4 +23,4 @@ exports.Listener = require('./listener');
* Version
*/
exports.version = '0.6.9';
exports.version = '0.6.17';

View File

@@ -21,7 +21,9 @@ Flashsocket.init = function(listener){
if (listeners.length === 0 && netserver){
try {
netserver.close();
} catch(e){}
} catch(e){
listener.options.log('flashsocket netserver close error - ' + e.stack)
}
}
});

View File

@@ -32,7 +32,9 @@ HTMLFile.prototype._onConnect = function(req, res){
try {
var msg = qs.parse(body);
self._onMessage(msg.data);
} catch(e){}
} catch(e){
self.listener.options.log('htmlfile message handler error - ' + e.stack);
}
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('ok');
res.end();

View File

@@ -78,14 +78,14 @@ WebSocket.prototype._onConnect = function(req, socket){
try {
this.connection.write(headers.concat('', '').join('\r\n'));
this.connection.setTimeout(0);
this.connection.setNoDelay(true);
this.connection.setEncoding('utf-8');
} catch(e){
this._onClose();
return;
}
this.connection.setTimeout(0);
this.connection.setNoDelay(true);
this.connection.setEncoding('utf-8');
if (this.waitingForNonce) {
// Since we will be receiving the binary nonce through the normal HTTP
// data event, set the connection to 'binary' temporarily
@@ -99,18 +99,16 @@ WebSocket.prototype._onConnect = function(req, socket){
this.buffer = "";
this.connection.addListener('data', function(data){
self.buffer += data;
if (self.waitingForNonce) {
self.buffer += data;
if (self.buffer.length < 8) { return; }
// Restore the connection to utf8 encoding after receiving the nonce
self.connection.setEncoding('utf8');
self.waitingForNonce = false;
// Stuff the nonce into the location where it's expected to be
self.upgradeHead = self.buffer.substr(0,8);
self.buffer = self.buffer.substr(8);
if (self.buffer.length > 0) {
self.parser.add(self.buffer);
}
self.buffer = '';
if (self._proveReception(self._headers)) { self._payload(); }
return;
}

View File

@@ -46,7 +46,9 @@ Multipart.prototype._onConnect = function(req, res){
try {
var msg = qs.parse(body);
self._onMessage(msg.data);
} catch(e){}
} catch(e){
self.listener.options.log('xhr-multipart message handler error - ' + e.stack);
}
res.writeHead(200, headers);
res.write('ok');
res.end();

View File

@@ -48,7 +48,9 @@ Polling.prototype._onConnect = function(req, res){
// optimization: just strip first 5 characters here?
var msg = qs.parse(body);
self._onMessage(msg.data);
} catch(e){}
} catch(e){
self.listener.options.log('xhr-polling message handler error - ' + e.stack);
}
res.writeHead(200, headers);
res.write('ok');
res.end();
@@ -67,7 +69,7 @@ Polling.prototype._write = function(message){
var headers = {'Content-Type': 'text/plain; charset=UTF-8', 'Content-Length': Buffer.byteLength(message)};
// https://developer.mozilla.org/En/HTTP_Access_Control
if (this.request.headers.origin && this._verifyOrigin(this.request.headers.origin)){
headers['Access-Control-Allow-Origin'] = this.request.headers.origin;
headers['Access-Control-Allow-Origin'] = (this.request.headers.origin === 'null' ? '*' : this.request.headers.origin);
if (this.request.headers.cookie) headers['Access-Control-Allow-Credentials'] = 'true';
}
this.response.writeHead(200, headers);

View File

@@ -1,17 +1,21 @@
{ "name" : "socket.io"
, "description" : "The cross-browser WebSocket"
, "version" : "0.6.9"
, "author" : "LearnBoost"
, "licenses" :
[ { "type" : "MIT"
, "url" : "http://github.com/learnboost/Socket.IO-node/raw/master/README.md"
{
"name": "socket.io"
, "description": "The cross-browser WebSocket"
, "version": "0.6.17"
, "author": "Guillermo Rauch <guillermo@learnboost.com>"
, "contributors": [
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
, { "name": "Arnout Kazemier", "email": "info@3rd-eden.com" }
]
, "licenses": [{
"type": "MIT"
, "url": "http://github.com/learnboost/Socket.IO-node/raw/master/README.md"
}]
, "repository": {
"type": "git"
, "url": "http://github.com/learnboost/Socket.IO-node.git"
}
]
, "repository" :
{ "type" : "git"
, "url" : "http://github.com/learnboost/Socket.IO-node.git"
}
, "engine" : [ "node >=0.1.102" ]
, "main" : "./index"
, "scripts" : { "test" : "make test" }
, "engine": [ "node >=0.1.102" ]
, "main": "./index"
, "scripts": { "test" : "make test" }
}