@JSConstructor public static Object newTCPImpl( Context cx, Object[] args, Function ctorObj, boolean inNewExpr) { TCPImpl tcp = new TCPImpl(); tcp.ref(); return tcp; }
@JSFunction public static void close(Context cx, Scriptable thisObj, Object[] args, Function func) { Function callback = functionArg(args, 0, false); TCPImpl self = (TCPImpl) thisObj; self.doClose(cx, callback); }
@JSFunction public static Object shutdown(Context cx, Scriptable thisObj, Object[] args, Function func) { TCPImpl tcp = (TCPImpl) thisObj; clearErrno(); QueuedWrite qw = (QueuedWrite) cx.newObject(thisObj, QueuedWrite.CLASS_NAME); qw.shutdown = true; tcp.offerWrite(qw, cx); return qw; }
@JSFunction public static Object writeBuffer(Context cx, Scriptable thisObj, Object[] args, Function func) { ensureArg(args, 0); Buffer.BufferImpl buf = (Buffer.BufferImpl) args[0]; TCPImpl tcp = (TCPImpl) thisObj; clearErrno(); QueuedWrite qw = (QueuedWrite) cx.newObject(thisObj, QueuedWrite.CLASS_NAME); ByteBuffer bbuf = buf.getBuffer(); qw.initialize(bbuf); tcp.byteCount += bbuf.remaining(); tcp.offerWrite(qw, cx); return qw; }
private void serverSelected(SelectionKey key) { if (!key.isValid()) { return; } if (log.isDebugEnabled()) { log.debug("Server selected: a = {}", key.isAcceptable()); } Context cx = Context.getCurrentContext(); if (key.isAcceptable()) { SocketChannel child = null; do { try { child = svrChannel.accept(); if (child != null) { if (log.isDebugEnabled()) { log.debug("Accepted new socket {}", child); } boolean success = false; try { getRunner().registerCloseable(child); TCPImpl sock = (TCPImpl) cx.newObject(this, CLASS_NAME); sock.initializeClient(child); if (onConnection != null) { onConnection.call(cx, onConnection, this, new Object[] {sock}); } success = true; } finally { if (!success) { getRunner().unregisterCloseable(child); try { child.close(); } catch (IOException ioe) { log.debug("Error closing channel that might be closed: {}", ioe); } } } } } catch (ClosedChannelException cce) { log.debug("Server channel has been closed"); break; } catch (IOException ioe) { log.error("Error accepting a new socket: {}", ioe); } } while (child != null); } }
@JSFunction public static Object connect(Context cx, Scriptable thisObj, Object[] args, Function func) { final TCPImpl tcp = (TCPImpl) thisObj; String host = stringArg(args, 0); int port = intArg(args, 1); boolean success = false; SocketChannel newChannel = null; try { InetSocketAddress targetAddress = new InetSocketAddress(host, port); NetworkPolicy netPolicy = tcp.getNetworkPolicy(); if ((netPolicy != null) && !netPolicy.allowConnection(targetAddress)) { log.debug("Disallowed connection to {} due to network policy", targetAddress); setErrno(Constants.EINVAL); return null; } if (log.isDebugEnabled()) { log.debug("Client connecting to {}:{}", host, port); } clearErrno(); if (tcp.boundAddress == null) { newChannel = SocketChannel.open(); } else { newChannel = SocketChannel.open(tcp.boundAddress); } tcp.clientChannel = newChannel; getRunner().registerCloseable(newChannel); tcp.clientInit(); tcp.clientChannel.connect(targetAddress); tcp.selKey = tcp.clientChannel.register( getRunner().getSelector(), SelectionKey.OP_CONNECT, new SelectorHandler() { @Override public void selected(SelectionKey key) { tcp.clientSelected(key); } }); tcp.pendingConnect = (PendingOp) cx.newObject(thisObj, PendingOp.CLASS_NAME); success = true; return tcp.pendingConnect; } catch (IOException ioe) { log.debug("Error on connect: {}", ioe); setErrno(Constants.EIO); return null; } finally { if (!success && (newChannel != null)) { getRunner().unregisterCloseable(newChannel); try { newChannel.close(); } catch (IOException ioe) { log.debug("Error closing channel that might be closed: {}", ioe); } } } }