chrome-net
Advanced tools
Comparing version 1.3.0 to 2.0.0
199
index.js
@@ -16,2 +16,46 @@ /** | ||
// Track open servers and sockets to route incoming sockets (via onAccept and onReceive) | ||
// to the right handlers. | ||
var servers = {} | ||
var sockets = {} | ||
if (typeof chrome !== 'undefined') { | ||
chrome.sockets.tcpServer.onAccept.addListener(onAccept) | ||
chrome.sockets.tcpServer.onAcceptError.addListener(onAcceptError) | ||
chrome.sockets.tcp.onReceive.addListener(onReceive) | ||
chrome.sockets.tcp.onReceiveError.addListener(onReceiveError) | ||
} | ||
function onAccept (info) { | ||
if (info.socketId in servers) { | ||
servers[info.socketId]._onAccept(info.clientSocketId) | ||
} else { | ||
console.error('Unknown server socket id: ' + info.socketId) | ||
} | ||
} | ||
function onAcceptError (info) { | ||
if (info.socketId in servers) { | ||
servers[info.socketId]._onAcceptError(info.resultCode) | ||
} else { | ||
console.error('Unknown server socket id: ' + info.socketId) | ||
} | ||
} | ||
function onReceive (info) { | ||
if (info.socketId in sockets) { | ||
sockets[info.socketId]._onReceive(info.data) | ||
} else { | ||
console.error('Unknown socket id: ' + info.socketId) | ||
} | ||
} | ||
function onReceiveError (info) { | ||
if (info.socketId in sockets) { | ||
sockets[info.socketId]._onReceiveError(info.resultCode) | ||
} else { | ||
console.error('Unknown socket id: ' + info.socketId) | ||
} | ||
} | ||
/** | ||
@@ -151,12 +195,9 @@ * Creates a new TCP server. The connectionListener argument is automatically | ||
chrome.socket.create('tcp', {}, function (createInfo) { | ||
chrome.sockets.tcpServer.create(function (createInfo) { | ||
self.id = createInfo.socketId | ||
chrome.socket.listen(self.id, | ||
address, | ||
port, | ||
backlog, | ||
function (result) { | ||
chrome.sockets.tcpServer.listen(self.id, address, port, backlog, function (result) { | ||
if (result < 0) { | ||
self.emit('error', new Error('Socket ' + self.id + ' failed to listen')) | ||
self.emit('error', new Error('Socket ' + self.id + ' failed to listen. ' + | ||
chrome.runtime.lastError.message)) | ||
self._destroy() | ||
@@ -169,4 +210,3 @@ return | ||
chrome.socket.accept(self.id, self._onAccept.bind(self)) | ||
servers[self.id] = self | ||
self.emit('listening') | ||
@@ -179,17 +219,10 @@ }) | ||
Server.prototype._onAccept = function (acceptInfo) { | ||
Server.prototype._onAccept = function (clientSocketId) { | ||
var self = this | ||
if (acceptInfo.resultCode < 0) { | ||
self.emit('error', new Error('Socket ' + self.id + ' failed to accept (' + | ||
acceptInfo.resultCode + ')')) | ||
self._destroy() | ||
return | ||
} | ||
// Set the `maxConnections property to reject connections when the server's | ||
// Set the `maxConnections` property to reject connections when the server's | ||
// connection count gets high. | ||
if (self.maxConnections && self._connections >= self.maxConnections) { | ||
chrome.socket.disconnect(acceptInfo.socketId) | ||
chrome.socket.destroy(acceptInfo.socketId) | ||
chrome.sockets.tcpServer.disconnect(clientSocketId) | ||
chrome.sockets.tcpServer.close(clientSocketId) | ||
console.warn('Rejected connection - hit `maxConnections` limit') | ||
@@ -203,7 +236,18 @@ return | ||
server: self, | ||
id: acceptInfo.socketId | ||
id: clientSocketId | ||
}) | ||
self.emit('connection', acceptedSocket) | ||
acceptedSocket.on('connect', function () { | ||
self.emit('connection', acceptedSocket) | ||
}) | ||
chrome.sockets.tcp.setPaused(clientSocketId, false) | ||
} | ||
Server.prototype._onAcceptError = function (resultCode) { | ||
var self = this | ||
self.emit('error', new Error('Socket ' + self.id + ' failed to accept (' + | ||
resultCode + ')')) | ||
self._destroy() | ||
} | ||
/** | ||
@@ -230,11 +274,11 @@ * Stops the server from accepting new connections and keeps existing | ||
chrome.socket.disconnect(self.id) | ||
chrome.socket.destroy(self.id) | ||
this._destroyed = true | ||
this._connections = 0 | ||
delete servers[self.id] | ||
self.emit('close') | ||
return this | ||
chrome.sockets.tcpServer.disconnect(self.id, function () { | ||
chrome.sockets.tcpServer.close(self.id, function () { | ||
self.emit('close') | ||
}) | ||
}) | ||
} | ||
@@ -355,4 +399,2 @@ | ||
options.decodeStrings = false // we will handle strings directly | ||
stream.Duplex.call(self, options) | ||
@@ -369,3 +411,2 @@ | ||
self._connecting = false | ||
self._outstandingRead = false | ||
@@ -376,3 +417,3 @@ if (options.server) { | ||
// If server socket, then it's already connected. | ||
// For incoming sockets (from server), it's already connected. | ||
self._connecting = true | ||
@@ -412,5 +453,6 @@ self._onConnect() | ||
return | ||
self._connecting = true | ||
var port = Number(options.port) | ||
if (is.isFunction(cb)) { | ||
@@ -420,12 +462,8 @@ self.once('connect', cb) | ||
chrome.socket.create('tcp', {}, function (createInfo) { | ||
chrome.sockets.tcp.create(function (createInfo) { | ||
self.id = createInfo.socketId | ||
chrome.socket.connect(self.id, | ||
options.host, | ||
Number(options.port), | ||
function (result) { | ||
chrome.sockets.tcp.connect(self.id, options.host, port, function (result) { | ||
if (result < 0) { | ||
self.destroy(new Error('Socket ' + self.id + ' connect error ' + | ||
result)) | ||
self.destroy(new Error('Socket ' + self.id + ' connect error ' + result)) | ||
return | ||
@@ -444,3 +482,4 @@ } | ||
chrome.socket.getInfo(self.id, function (result) { | ||
sockets[self.id] = self | ||
chrome.sockets.tcp.getInfo(self.id, function (result) { | ||
self.remoteAddress = result.peerAddress | ||
@@ -514,7 +553,9 @@ self.remotePort = result.peerPort | ||
chrome.socket.write(self.id, buffer.toArrayBuffer(), function (writeInfo) { | ||
if (writeInfo.bytesWritten < 0) { | ||
var err = new Error('Socket ' + self.id + ' write error ' + | ||
writeInfo.bytesWritten) | ||
self.destroy(err, callback) | ||
// assuming buffer is browser implementation (`buffer` package on npm) | ||
chrome.sockets.tcp.send(self.id, buffer.buffer /* buffer.toArrayBuffer() is slower */, | ||
function (sendInfo) { | ||
if (sendInfo.resultCode < 0) { | ||
var err = new Error('Socket ' + self.id + ' write error: ' + sendInfo.resultCode) | ||
callback(err) | ||
self.destroy(err) | ||
} else { | ||
@@ -536,28 +577,25 @@ self._resetTimeout() | ||
if (self._outstandingRead) | ||
return | ||
chrome.sockets.tcp.setPaused(self.id, false) | ||
} | ||
self._outstandingRead = true | ||
Socket.prototype._onReceive = function (data) { | ||
var self = this | ||
var buffer = new Buffer(new Uint8Array(data)) | ||
chrome.socket.read(self.id, bufferSize, function (readInfo) { | ||
self._outstandingRead = false | ||
if (readInfo.resultCode === 0) { | ||
self.push(null) | ||
self.destroy() | ||
self.bytesRead += buffer.length | ||
self._resetTimeout() | ||
} else if (readInfo.resultCode < 0) { | ||
self.destroy(new Error('Socket ' + self.id + ' read error ' + | ||
readInfo.resultCode)) | ||
if (!self.push(buffer)) { // if returns false, then apply backpressure | ||
chrome.sockets.tcp.setPaused(self.id, true) | ||
} | ||
} | ||
} else { | ||
var buffer = readInfo.data | ||
buffer = new Buffer(new Uint8Array(buffer)) | ||
self.bytesRead += buffer.length | ||
self._resetTimeout() | ||
if (self.push(buffer)) // if returns true, then try to read more | ||
self._read(bufferSize) | ||
} | ||
}) | ||
Socket.prototype._onReceiveError = function (resultCode) { | ||
var self = this | ||
if (resultCode === -100) { | ||
self.push(null) | ||
self.destroy() | ||
} else if (resultCode < 0) { | ||
self.destroy(new Error('Socket ' + self.id + ' receive error ' + resultCode)) | ||
} | ||
} | ||
@@ -616,16 +654,17 @@ | ||
if (this.server) { | ||
this.server._connections -= 1 | ||
} | ||
self._connecting = false | ||
this.readable = this.writable = false | ||
chrome.socket.disconnect(self.id) | ||
chrome.socket.destroy(self.id) | ||
self.emit('close', !!exception) | ||
fireErrorCallbacks() | ||
self.destroyed = true | ||
delete sockets[self.id] | ||
if (this.server) { | ||
this.server._connections -= 1 | ||
} | ||
chrome.sockets.tcp.disconnect(self.id, function () { | ||
chrome.sockets.tcp.close(self.id, function () { | ||
self.emit('close', !!exception) | ||
fireErrorCallbacks() | ||
}) | ||
}) | ||
} | ||
@@ -688,3 +727,3 @@ | ||
if (!callback) callback = function () {} | ||
chrome.socket.setNoDelay(self.id, noDelay, callback) | ||
chrome.sockets.tcp.setNoDelay(self.id, noDelay, callback) | ||
} | ||
@@ -713,3 +752,3 @@ | ||
if (!callback) callback = function () {} | ||
chrome.socket.setKeepAlive(self.id, !!enable, ~~(initialDelay / 1000), | ||
chrome.sockets.tcp.setKeepAlive(self.id, !!enable, ~~(initialDelay / 1000), | ||
callback) | ||
@@ -716,0 +755,0 @@ } |
{ | ||
"name": "chrome-net", | ||
"description": "Use the Node `net` API in Chrome Apps", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"author": "Feross Aboukhadijeh <feross@feross.org> (http://feross.org/)", | ||
@@ -6,0 +6,0 @@ "bugs": { |
@@ -15,14 +15,18 @@ { | ||
"permissions": [ | ||
{ | ||
"socket": [ | ||
"tcp-connect:*:*", | ||
"tcp-listen::*", | ||
"udp-send-to::*", | ||
"udp-bind::*" | ||
] | ||
}, | ||
"http://*/*" | ||
"*://*/*" | ||
], | ||
"icons": { "16": "calculator-16.png", "128": "calculator-128.png" } | ||
"sockets": { | ||
"udp": { | ||
"bind": "*", | ||
"send": "*" | ||
}, | ||
"tcp": { | ||
"connect": "*" | ||
}, | ||
"tcpServer": { | ||
"listen": "*" | ||
} | ||
} | ||
} |
@@ -14,5 +14,6 @@ var dgram = require('chrome-dgram') | ||
var readySock | ||
server.on('listening', function () { | ||
// Report to node that the TCP server is listening | ||
var readySock = dgram.createSocket('udp4') | ||
readySock = dgram.createSocket('udp4') | ||
readySock.on('error', function (err) { | ||
@@ -28,4 +29,3 @@ console.error(err.stack) | ||
sock.on('error', function (err) { | ||
console.error(err) | ||
console.log(err.stack) | ||
console.error(err.stack) | ||
sock.write(err.message) | ||
@@ -35,4 +35,2 @@ }) | ||
sock.on('data', function (data) { | ||
console.log('data') | ||
console.log(data.toString()) | ||
if (data.toString() === 'beep') { | ||
@@ -44,4 +42,9 @@ sock.write('boop') | ||
}) | ||
// test that client stream ends correctly | ||
sock.on('end', function () { | ||
readySock.send('end', 0, 'end'.length, READY_PORT, '127.0.0.1') | ||
}) | ||
}) | ||
server.listen(LISTEN_PORT) |
@@ -32,24 +32,28 @@ var async = require('async') | ||
readySocket.on('message', function (message, remote) { | ||
t.equal(message.toString(), 'listening', 'Client listens') | ||
if (message.toString() === 'listening') { | ||
t.pass('Client listens') | ||
// Do TCP echo test | ||
var socket = net.createConnection({ port: r.listenPort }) | ||
socket.on('connect', function () { | ||
socket.write('beep', 'utf8') | ||
}) | ||
// Do TCP echo test | ||
var socket = net.createConnection({ port: r.listenPort }) | ||
socket.on('connect', function () { | ||
socket.write('beep', 'utf8') | ||
}) | ||
var i = 0 | ||
socket.on('data', function (data) { | ||
if (i === 0) { | ||
t.equal(data.toString(), 'boop', 'Beep/boop looks good') | ||
readySocket.close() | ||
socket.end() | ||
child.kill() | ||
t.end() | ||
} else { | ||
t.fail('TCP server sent unexpected data') | ||
} | ||
i += 1 | ||
}) | ||
var i = 0 | ||
socket.on('data', function (data) { | ||
if (i === 0) { | ||
t.equal(data.toString(), 'boop', 'Beep/boop looks good') | ||
socket.end() | ||
} else { | ||
t.fail('TCP server sent unexpected data') | ||
} | ||
i += 1 | ||
}) | ||
} else if (message.toString() === 'end') { | ||
t.pass('Client stream ended correctly') | ||
readySocket.close() | ||
child.kill() | ||
t.end() | ||
} | ||
}) | ||
@@ -56,0 +60,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
7221
244630
14