1 | SocketIoClient = require('socket.io-client')
|
2 | SocketIoStream = require('socket.io-stream')
|
3 | OS = require('os')
|
4 |
|
5 |
|
6 | Base = require('../base')
|
7 | Caller = require('./caller')
|
8 | ClientInfo = require('./client_info')
|
9 | Connector = require('./connector')
|
10 | Crypto = require('./crypto')
|
11 | HttpProxy = require('./http_proxy')
|
12 | Logger = require('./logger')
|
13 | PolyglotRelay = require('./polyglot_relay')
|
14 | Publisher = require('./publisher')
|
15 |
|
16 |
|
17 | EVENTS = [ 'connect', 'connect_error', 'connect_timeout', 'reconnect', 'reconnect_error', 'reconnect_failed', 'error', 'disconnect', 'open', 'close', 'reconnect_attempt' ]
|
18 |
|
19 | debug = Base.logger('connector')
|
20 |
|
21 | isHttpProxy = false
|
22 | isRelay = false
|
23 |
|
24 |
|
25 | socket = null
|
26 | proxyData = null
|
27 | isHttpProxySetup = false
|
28 |
|
29 |
|
30 | exports.connectToProxy = (data) ->
|
31 | debug('connectToProxy', data)
|
32 |
|
33 | socket = null
|
34 | proxyData = null
|
35 | isHttpProxySetup = false
|
36 | Logger.loadFilter ->
|
37 | proxyData = data
|
38 | proxyData.proxyUrl = "https://"+Base.env.IX_PROXY_HOST_OVERRIDE if Base.env.IX_PROXY_HOST_OVERRIDE
|
39 | console.log('Connecting to '+proxyData.proxyUrl+'...')
|
40 | socket = SocketIoClient(proxyData.proxyUrl, { reconnection: false, multiplex: false, rejectUnauthorized: Base.env.IX_PROXY_HOST_ALLOW_UNVERIFIED != 'TRUE' })
|
41 | setDebugHandlers(socket, EVENTS)
|
42 | setDebugHandlers(socket.io, EVENTS, 'manager:')
|
43 | socket.on('connect', onConnect)
|
44 | socket.on 'connect_error', (err) ->
|
45 | console.log('Connect error: '+err)
|
46 | reconnect()
|
47 | socket.on 'disconnect', (cause) ->
|
48 | console.log('Disconnected from '+proxyData.proxyUrl+': '+cause)
|
49 | reconnect()
|
50 | unless isHttpProxy
|
51 | socket.on('ix-call', onIxCall)
|
52 | socket.on('ix-ping', onIxPing)
|
53 | socket.on('ix-x', onIxX)
|
54 |
|
55 | exports.connectRelayToProxy = (data) ->
|
56 | debug('connectRelayToProxy', data)
|
57 | isRelay = true
|
58 | exports.connectToProxy(data)
|
59 |
|
60 | exports.connectHttpToProxy = (upstream, data) ->
|
61 | debug('connectHttpToProxy', upstream, data)
|
62 | isHttpProxy = true
|
63 | HttpProxy.setupHttpProxy(upstream)
|
64 | exports.connectToProxy(data)
|
65 |
|
66 |
|
67 | onConnect = ->
|
68 | debug('connect')
|
69 | ClientInfo.clientInfo()
|
70 | .then (clientInfo) ->
|
71 | debug('clientInfo', clientInfo)
|
72 | socket.emit 'set-client',
|
73 | apiConfig: Base.apiConfig()
|
74 | proxyUrl: proxyData.proxyUrl
|
75 | proxyExport: proxyData.proxyExport
|
76 | device: { key: clientInfo.deviceKey, secret: clientInfo.deviceSecret }
|
77 | deviceKey: clientInfo.deviceKey
|
78 | deviceSecret: clientInfo.deviceSecret
|
79 | hostname: OS.hostname()
|
80 | pid: process.pid
|
81 | processKey: getProcessKey()
|
82 | clientInfo: clientInfo
|
83 | , (err, connectData) ->
|
84 | debug('connect result', err, connectData)
|
85 | if err
|
86 | console.log('Connect error: Unable to complete connection to '+proxyData.proxyUrl+': '+JSON.stringify(err))
|
87 | throw new Error(err)
|
88 | else
|
89 | if isHttpProxy
|
90 | SocketIoStream.forceBase64 = true unless connectData.enableBinaryStream
|
91 | debug('SocketIoStream.forceBase64', SocketIoStream.forceBase64)
|
92 | unless isHttpProxySetup
|
93 | isHttpProxySetup = true
|
94 | streamSocket = SocketIoStream(socket)
|
95 | setDebugHandlers(streamSocket, EVENTS, 'stream:')
|
96 | streamSocket.on('http-proxy', HttpProxy.onHttpProxy)
|
97 | console.log('Connected to '+proxyData.proxyUrl+'.')
|
98 |
|
99 | reconnect = ->
|
100 | setTimeout ->
|
101 | Publisher.getProxyForReconnect(isHttpProxy)
|
102 | .then (data) ->
|
103 | Connector.connectToProxy(data)
|
104 | , (e) ->
|
105 | console.error('ERROR WHILE RECONNECTING', e)
|
106 | reconnect()
|
107 | , 1000
|
108 |
|
109 |
|
110 | onIxCall = (data, responder) ->
|
111 | debug('ix-call', arguments)
|
112 | try
|
113 | Logger.logCallRequest(data)
|
114 | responder = Logger.wrapResponder(data, debug.wrap(responder))
|
115 | catch e
|
116 | try
|
117 | if isRelay
|
118 | Caller.ixCall(data, responder, PolyglotRelay.invoker)
|
119 | else
|
120 | Caller.ixCallNodejs(data, responder)
|
121 | catch e
|
122 | responder(e)
|
123 |
|
124 | onIxPing = (replyData, responder) ->
|
125 | debug('ix-ping', replyData)
|
126 | responder(null, replyData)
|
127 |
|
128 | onIxX = (cipherParams, responder) ->
|
129 | debug('ix-x', cipherParams)
|
130 | Crypto.decrypt cipherParams, (err, data) ->
|
131 | if err
|
132 | responder.call(err); return
|
133 | onIxCall(data, Crypto.encryptingResponder(responder))
|
134 |
|
135 |
|
136 | PROCESS_KEY = null
|
137 | getProcessKey = ->
|
138 | PROCESS_KEY ?= (new Date()).getTime()+'-'+Math.floor((Math.random()*1000000))
|
139 | PROCESS_KEY
|
140 |
|
141 | setDebugHandlers = (socket, events, prefix) ->
|
142 | prefix = prefix || ''
|
143 | for event in events
|
144 | socket.on(event, debugHandlerFor(prefix+event))
|
145 |
|
146 | debugHandlerFor = (type) ->
|
147 | (args...) ->
|
148 | args.unshift('event:'+type)
|
149 | debug.apply(this, args)
|