/* Public API. */ exports.create = create; /* Implementation. */ function create(args) { var socket, reconnectTO = 1000, decayedTO = 1, listenSocketTimeout = 0, failCount = 0, retryPaused = false; function listenSocket() { listenSocketTimeout = 0; socket = Ti.Network && Ti.Network.Socket && Ti.Network.Socket.createTCP({ host: args.host, port: args.ports && args.ports[failCount % args.ports.length] || args.port, connected: socketConnected, error: disconnectAndRetry }); socket && socket.connect(); } function socketConnected(e) { failCount = 0; Ti.Stream.pump(e.socket, pumpSocket, 1024, true); args.connected && args.connected(); } function disconnect() { if (listenSocketTimeout) { clearTimeout(listenSocketTimeout); listenSocketTimeout = 0; } if (socket) { try { socket.close(); } catch (e) { // Oh, well... } socket = null; } decayedTO = decayedTO * 2; } function retry() { listenSocketTimeout = setTimeout(listenSocket, decayedTO); } function resume() { decayedTO = reconnectTO; retry(); } function disconnectAndRetry() { failCount += 1; disconnect(); retry(); } function isConnected() { return socket && socket.state == Ti.Network.Socket.CONNECTED } function write(str) { if (!isConnected()) { return false; } else { //noinspection JSValidateTypes socket.write(Ti.createBuffer({ value: str })); return true; } } function pauseRetry() { retryPaused = listenSocketTimeout > 0; } function resumeRetry() { if (retryPaused) { retryPaused = false; retry(); } } function pumpSocket(e) { // Has the remote socket closed its end? if (e.bytesProcessed < 0) { disconnectAndRetry(); return; } try { e.buffer && args.read && args.read(e.buffer.toString()); } catch (ex) { Ti.API.error('[LOX] Socket Error: ' + ex); } } function clean() { disconnect(); args = socket = decayedTO = retryPaused = listenSocketTimeout = failCount = null; } return { start: retry, isConnected: isConnected, write: write, pauseRetry: pauseRetry, resumeRetry: resumeRetry, resume: resume, disconnect: disconnect, clean: clean }; }