Created
November 21, 2012 21:13
-
-
Save rgarcia/4127760 to your computer and use it in GitHub Desktop.
node tcp proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
net = require 'net' | |
assert = require 'assert' | |
settings = | |
# listen on this port | |
proxy_server: | |
host: 'localhost' | |
port: 4731 | |
# and proxy this guy | |
gearman_server: | |
host: 'localhost' | |
port: 4730 | |
console.log settings | |
# every time we initiate (receive) an outbound (inbound) connection, assign a unique id to it | |
ob_conn_next_id = 1 | |
ib_conn_next_id = 1 | |
# keep track of how many outbound (inbound) connections we have outstanding | |
ob_conns = 0 | |
ib_conns = 0 | |
# open server to receive inbound connections | |
server = new net.Server() | |
server.on 'listening', () -> console.log "SERVER listening: #{JSON.stringify server.address()}" | |
server.on 'close', () -> console.log "SERVER close" | |
server.on 'error', (err) -> console.log "SERVER error: #{JSON.stringify err}" | |
server.on 'connection', (ib_conn) -> | |
console.log 'SERVER connection' | |
# open a connection to gearman | |
# if gearman sends us data, relay it on to the inbound connection | |
# if gearman closes our connection (it shutdown/crashed), times out, or otherwise throws an | |
# error, close the inbound connection | |
# TODO: to be a full proxy we should refuse connections when gearman is unavailable...not sure if we can do this | |
ob_conn_id = null | |
ob_conn = net.connect settings.gearman_server | |
ob_conn.on 'connect', () -> | |
ob_conn_id = ob_conn_next_id | |
ob_conn_next_id += 1 | |
ob_conns += 1 | |
console.log "OUTBOUND id=#{ob_conn_id} connected. total outbound connections=#{ob_conns}" | |
ob_conn.on 'data', (data) -> | |
console.log "OUTBOUND id=#{ob_conn_id} data", data | |
ib_conn.write data # relay gearman data back to inbound | |
ob_conn.on 'drain', () -> | |
console.log "OUTBOUND id=#{ob_conn_id} drain" | |
ob_conn.on 'error', (err) -> | |
console.log "OUTBOUND id=#{ob_conn_id} error", err | |
ib_conn.end() | |
ob_conn.on 'end', () -> | |
ob_conns -= 1 | |
console.log "OUTBOUND id=#{ob_conn_id} end. total outbound connections=#{ob_conns}" | |
ib_conn.end() | |
ob_conn.on 'timeout', () -> | |
console.log "OUTBOUND id=#{ob_conn_id} timeout" | |
ib_conn.end() | |
ob_conn.on 'close', () -> | |
console.log "OUTBOUND id=#{ob_conn_id} close" | |
# if the inbound connection sends data, relay it to gearman | |
# if the inbound connection ends, kill our gearman connection | |
ib_conn_id = null | |
ib_conn.on 'connect', () -> | |
ib_conn_id = ib_conn_next_id | |
ib_conn_next_id += 1 | |
ib_conns += 1 | |
assert.equal ib_conns, server.connections | |
console.log "INBOUND id=#{ib_conn_id} connected. total inbound connections=#{ib_conns}" | |
ib_conn.on 'data', (data) -> | |
console.log "INBOUND id=#{ib_conn_id} data", data | |
ob_conn.write data # relay inbound data to gearman | |
ib_conn.on 'drain', () -> | |
console.log "INBOUND id=#{ib_conn_id} drain" | |
ib_conn.on 'error', (err) -> | |
console.log "INBOUND id=#{ib_conn_id} error", err | |
ib_conn.on 'end', () -> | |
ib_conns -= 1 | |
console.log "INBOUND id=#{ib_conn_id} end. total inbound connections=#{ib_conns}" | |
assert.equal ib_conns, server.connections, "expected there to be #{ib_conns} inbound server connections, but server reports #{server.connections}" | |
ob_conn.end() | |
ib_conn.on 'timeout', () -> | |
console.log "INBOUND id=#{ib_conn_id} timeout" | |
ib_conn.on 'close', () -> | |
console.log "INBOUND id=#{ib_conn_id} close" | |
assert.equal ib_conns, server.connections | |
server.listen settings.proxy_server.port, settings.proxy_server.host |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment