List of usage examples for io.netty.channel ChannelFuture isSuccess
boolean isSuccess();
From source file:com.vexsoftware.votifier.NuVotifierBukkit.java
License:Open Source License
@Override public void onEnable() { NuVotifierBukkit.instance = this; // Set the plugin version. version = getDescription().getVersion(); if (!getDataFolder().exists()) { getDataFolder().mkdir();//from w w w .ja v a 2s .co m } // Handle configuration. File config = new File(getDataFolder() + "/config.yml"); YamlConfiguration cfg; File rsaDirectory = new File(getDataFolder() + "/rsa"); /* * Use IP address from server.properties as a default for * configurations. Do not use InetAddress.getLocalHost() as it most * likely will return the main server address instead of the address * assigned to the server. */ String hostAddr = Bukkit.getServer().getIp(); if (hostAddr == null || hostAddr.length() == 0) hostAddr = "0.0.0.0"; /* * Create configuration file if it does not exists; otherwise, load it */ if (!config.exists()) { try { // First time run - do some initialization. getLogger().info("Configuring Votifier for the first time..."); // Initialize the configuration file. config.createNewFile(); // Load and manually replace variables in the configuration. String cfgStr = new String(ByteStreams.toByteArray(getResource("bukkitConfig.yml")), StandardCharsets.UTF_8); String token = TokenUtil.newToken(); cfgStr = cfgStr.replace("%default_token%", token).replace("%ip%", hostAddr); Files.write(cfgStr, config, StandardCharsets.UTF_8); /* * Remind hosted server admins to be sure they have the right * port number. */ getLogger().info("------------------------------------------------------------------------------"); getLogger() .info("Assigning NuVotifier to listen on port 8192. If you are hosting Craftbukkit on a"); getLogger().info("shared server please check with your hosting provider to verify that this port"); getLogger().info("is available for your use. Chances are that your hosting provider will assign"); getLogger().info("a different port, which you need to specify in config.yml"); getLogger().info("------------------------------------------------------------------------------"); getLogger().info("Your default NuVotifier token is " + token + "."); getLogger().info("You will need to provide this token when you submit your server to a voting"); getLogger().info("list."); getLogger().info("------------------------------------------------------------------------------"); } catch (Exception ex) { getLogger().log(Level.SEVERE, "Error creating configuration file", ex); gracefulExit(); return; } } // Load configuration. cfg = YamlConfiguration.loadConfiguration(config); /* * Create RSA directory and keys if it does not exist; otherwise, read * keys. */ try { if (!rsaDirectory.exists()) { rsaDirectory.mkdir(); keyPair = RSAKeygen.generate(2048); RSAIO.save(rsaDirectory, keyPair); } else { keyPair = RSAIO.load(rsaDirectory); } } catch (Exception ex) { getLogger().log(Level.SEVERE, "Error reading configuration file or RSA tokens", ex); gracefulExit(); return; } debug = cfg.getBoolean("debug", false); boolean setUpPort = cfg.getBoolean("enableExternal", true); //Always default to running the external port if (setUpPort) { // Load Votifier tokens. ConfigurationSection tokenSection = cfg.getConfigurationSection("tokens"); if (tokenSection != null) { Map<String, Object> websites = tokenSection.getValues(false); for (Map.Entry<String, Object> website : websites.entrySet()) { tokens.put(website.getKey(), KeyCreator.createKeyFrom(website.getValue().toString())); getLogger().info("Loaded token for website: " + website.getKey()); } } else { String token = TokenUtil.newToken(); tokenSection = cfg.createSection("tokens"); tokenSection.set("default", token); tokens.put("default", KeyCreator.createKeyFrom(token)); try { cfg.save(config); } catch (IOException e) { getLogger().log(Level.SEVERE, "Error generating Votifier token", e); gracefulExit(); return; } getLogger().info("------------------------------------------------------------------------------"); getLogger().info("No tokens were found in your configuration, so we've generated one for you."); getLogger().info("Your default Votifier token is " + token + "."); getLogger().info("You will need to provide this token when you submit your server to a voting"); getLogger().info("list."); getLogger().info("------------------------------------------------------------------------------"); } // Initialize the receiver. final String host = cfg.getString("host", hostAddr); final int port = cfg.getInt("port", 8192); if (debug) getLogger().info("DEBUG mode enabled!"); final boolean disablev1 = cfg.getBoolean("disable-v1-protocol"); if (disablev1) { getLogger().info("------------------------------------------------------------------------------"); getLogger().info("Votifier protocol v1 parsing has been disabled. Most voting websites do not"); getLogger().info("currently support the modern Votifier protocol in NuVotifier."); getLogger().info("------------------------------------------------------------------------------"); } serverGroup = new NioEventLoopGroup(1); new ServerBootstrap().channel(NioServerSocketChannel.class).group(serverGroup) .childHandler(new ChannelInitializer<NioSocketChannel>() { @Override protected void initChannel(NioSocketChannel channel) throws Exception { channel.attr(VotifierSession.KEY).set(new VotifierSession()); channel.attr(VotifierPlugin.KEY).set(NuVotifierBukkit.this); channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler()); channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, !disablev1)); channel.pipeline().addLast("voteHandler", new VoteInboundHandler(NuVotifierBukkit.this)); } }).bind(host, port).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { serverChannel = future.channel(); getLogger() .info("Votifier enabled on socket " + serverChannel.localAddress() + "."); } else { SocketAddress socketAddress = future.channel().localAddress(); if (socketAddress == null) { socketAddress = new InetSocketAddress(host, port); } getLogger().log(Level.SEVERE, "Votifier was not able to bind to " + socketAddress, future.cause()); } } }); } else { getLogger().info( "You have enableExternal set to false in your config.yml. NuVotifier will NOT listen to votes coming in from an external voting list."); } ConfigurationSection forwardingConfig = cfg.getConfigurationSection("forwarding"); if (forwardingConfig != null) { String method = forwardingConfig.getString("method", "none").toLowerCase(); //Default to lower case for case-insensitive searches if ("none".equals(method)) { getLogger().info( "Method none selected for vote forwarding: Votes will not be received from a forwarder."); } else if ("pluginmessaging".equals(method)) { String channel = forwardingConfig.getString("pluginMessaging.channel", "NuVotifier"); try { forwardingMethod = new BukkitPluginMessagingForwardingSink(this, channel, this); getLogger().info("Receiving votes over PluginMessaging channel '" + channel + "'."); } catch (RuntimeException e) { getLogger().log(Level.SEVERE, "NuVotifier could not set up PluginMessaging for vote forwarding!", e); } } else { getLogger().severe( "No vote forwarding method '" + method + "' known. Defaulting to noop implementation."); } } }
From source file:com.vexsoftware.votifier.Votifier.java
License:Open Source License
@Mod.EventHandler public void onInit(FMLInitializationEvent event) throws IOException { // Handle configuration. if (!getDataFolder().exists()) { getDataFolder().mkdir();//from w w w.j av a2s . c om } File config = new File(getDataFolder() + "/config.yml"); ConfigurationLoader loader = YAMLConfigurationLoader.builder().setFile(config).build(); ConfigurationNode cfg = loader.load(); File rsaDirectory = new File(getDataFolder() + "/rsa"); /* * Use IP address from server.properties as a default for * configurations. Do not use InetAddress.getLocalHost() as it most * likely will return the main server address instead of the address * assigned to the server. */ String hostAddr = MinecraftServer.getServer().getHostname(); if (hostAddr == null || hostAddr.length() == 0) hostAddr = "0.0.0.0"; /* * Create configuration file if it does not exists; otherwise, load it */ if (!config.exists()) { try { // First time run - do some initialization. LOG.info("Configuring Votifier for the first time..."); // Initialize the configuration file. config.createNewFile(); cfg.getNode("host").setValue(hostAddr); cfg.getNode("port").setValue(8192); cfg.getNode("debug").setValue(false); /* * Remind hosted server admins to be sure they have the right * port number. */ LOG.info("------------------------------------------------------------------------------"); LOG.info("Assigning Votifier to listen on port 8192. If you are hosting Forge on a"); LOG.info("shared server please check with your hosting provider to verify that this port"); LOG.info("is available for your use. Chances are that your hosting provider will assign"); LOG.info("a different port, which you need to specify in config.yml"); LOG.info("------------------------------------------------------------------------------"); String token = TokenUtil.newToken(); ConfigurationNode tokenSection = cfg.getNode("tokens"); tokenSection.getNode("default").setValue(token); LOG.info("Your default Votifier token is " + token + "."); LOG.info("You will need to provide this token when you submit your server to a voting"); LOG.info("list."); LOG.info("------------------------------------------------------------------------------"); loader.save(cfg); } catch (Exception ex) { LOG.log(Level.FATAL, "Error creating configuration file", ex); gracefulExit(); return; } } else { // Load configuration. cfg = loader.load(); } /* * Create RSA directory and keys if it does not exist; otherwise, read * keys. */ try { if (!rsaDirectory.exists()) { rsaDirectory.mkdir(); keyPair = RSAKeygen.generate(2048); RSAIO.save(rsaDirectory, keyPair); } else { keyPair = RSAIO.load(rsaDirectory); } } catch (Exception ex) { LOG.fatal("Error reading configuration file or RSA tokens", ex); gracefulExit(); return; } // Load Votifier tokens. ConfigurationNode tokenSection = cfg.getNode("tokens"); if (tokenSection != null) { Map<Object, ? extends ConfigurationNode> websites = tokenSection.getChildrenMap(); for (Map.Entry<Object, ? extends ConfigurationNode> website : websites.entrySet()) { tokens.put((String) website.getKey(), KeyCreator.createKeyFrom(website.getValue().getString())); LOG.info("Loaded token for website: " + website.getKey()); } } else { LOG.warn("No websites are listed in your configuration."); } // Initialize the receiver. String host = cfg.getNode("host").getString(hostAddr); int port = cfg.getNode("port").getInt(8192); debug = cfg.getNode("debug").getBoolean(false); if (debug) LOG.info("DEBUG mode enabled!"); serverGroup = new NioEventLoopGroup(1); new ServerBootstrap().channel(NioServerSocketChannel.class).group(serverGroup) .childHandler(new ChannelInitializer<NioSocketChannel>() { @Override protected void initChannel(NioSocketChannel channel) throws Exception { channel.attr(VotifierSession.KEY).set(new VotifierSession()); channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler()); channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator()); channel.pipeline().addLast("voteHandler", new VoteInboundHandler()); } }).bind(host, port).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { serverChannel = future.channel(); LOG.info("Votifier enabled."); } else { LOG.fatal("Votifier was not able to bind to " + future.channel().localAddress(), future.cause()); } } }); }
From source file:com.vmware.dcp.common.http.netty.NettyChannelPool.java
License:Open Source License
public void connectOrReuse(String host, int port, boolean doNotReUse, Operation request) { if (request == null) { throw new IllegalArgumentException("request is required"); }//from w w w.j a v a2 s . c o m if (host == null) { request.fail(new IllegalArgumentException("host is required")); return; } if (port <= 0) { port = UriUtils.HTTP_DEFAULT_PORT; } try { String key = toConnectionKey(host, port); NettyChannelGroup group = getChannelGroup(key); NettyChannelContext context = null; synchronized (group) { if (!group.availableChannels.isEmpty() && !doNotReUse) { context = group.availableChannels.remove(group.availableChannels.size() - 1); context.updateLastUseTime(); } else if (group.inUseChannels.size() >= this.connectionLimit) { group.pendingRequests.add(request); return; } else { context = new NettyChannelContext(host, port, key); } if (context.getChannel() != null) { if (!context.getChannel().isOpen()) { context.close(); context = new NettyChannelContext(host, port, key); } } group.inUseChannels.add(context); } NettyChannelContext contextFinal = context; if (context.getChannel() != null) { context.setOperation(request); request.complete(); return; } ChannelFuture connectFuture = this.bootStrap.connect(context.host, context.port); connectFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { Channel ch = future.channel(); contextFinal.setChannel(ch).setOperation(request); request.complete(); } else { returnOrClose(contextFinal, true); fail(request, future.cause()); } } }); } catch (Throwable e) { fail(request, e); } }
From source file:com.vmware.dcp.common.http.netty.NettyWebSocketRequestHandler.java
License:Open Source License
private void performWebsocketHandshake(final ChannelHandlerContext ctx, FullHttpRequest nettyRequest) { WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(this.handshakePath, null, false);/*from w w w. jav a 2 s .c om*/ this.handshaker = factory.newHandshaker(nettyRequest); if (this.handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { ChannelPromise promise = new DefaultChannelPromise(ctx.channel()); promise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.channel().close(); } ctx.channel().closeFuture().addListener(f -> { for (java.util.Map.Entry<URI, Set<String>> e : NettyWebSocketRequestHandler.this.serviceSubscriptions .entrySet()) { WebSocketService svc = NettyWebSocketRequestHandler.this.webSocketServices .get(e.getKey()); if (svc != null) { deleteServiceSubscriptions(svc); } NettyWebSocketRequestHandler.this.host.stopService(svc); } }); } }); DefaultHttpHeaders responseHeaders = new DefaultHttpHeaders(); this.handshaker.handshake(ctx.channel(), nettyRequest, responseHeaders, promise); } }
From source file:com.vmware.dcp.common.JsWebSocket.java
License:Open Source License
/** * Standard constructor WebSocket(uri) available in JavaScript API * * @param endpointUri Websocket endpoint URI *//* w w w. ja va2 s .co m*/ public JsWebSocket(String endpointUri) throws Exception { URI uri = new URI(endpointUri); String scheme = uri.getScheme() == null ? WS_SCHEME : uri.getScheme(); final String host = uri.getHost() == null ? ServiceHost.LOCAL_HOST : uri.getHost(); final int port; if (uri.getPort() == -1) { if (WS_SCHEME.equalsIgnoreCase(scheme)) { port = 80; } else if (WSS_SCHEME.equalsIgnoreCase(scheme)) { port = 443; } else { port = -1; } } else { port = uri.getPort(); } if (!WS_SCHEME.equalsIgnoreCase(scheme) && !WSS_SCHEME.equalsIgnoreCase(scheme)) { System.err.println("Only WS(S) is supported."); return; } final boolean ssl = WSS_SCHEME.equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); } else { sslCtx = null; } this.group = new NioEventLoopGroup(); // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00. // If you change it to V00, ping is not supported and remember to change // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline. final WebSocketClientHandler handler = new WebSocketClientHandler(WebSocketClientHandshakerFactory .newHandshaker(uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders())); Bootstrap b = new Bootstrap(); b.group(this.group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline p = ch.pipeline(); if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc(), host, port)); } p.addLast(new HttpClientCodec(), new HttpObjectAggregator(8192), new WebSocketClientCompressionHandler(), handler); } }); this.channel = b.connect(uri.getHost(), port).sync().channel(); handler.handshakeFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { try { JsExecutor.executeSynchronously(() -> { if (future.isSuccess()) { if (JsWebSocket.this.onopen != null) { JsWebSocket.this.onopen.call(Context.getCurrentContext(), getParentScope(), JsWebSocket.this, new Object[] { null }); } } else { throw new RuntimeException(future.cause()); } }); } catch (Exception e) { e.printStackTrace(); } } }); }
From source file:com.vmware.dcp.common.WebSocketService.java
License:Open Source License
@Override public void handleRequest(Operation op) { prepareRequest(op);// w w w . j av a 2 s .c o m Operation.SerializedOperation serializedOperation = Operation.SerializedOperation.create(op); this.pendingOperations.put(op.getId(), op); ChannelFuture promise = this.ctx.writeAndFlush(new TextWebSocketFrame( "POST " + this.uri.toString() + Operation.CR_LF + Utils.toJson(serializedOperation))); promise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { op.fail(future.cause()); WebSocketService.this.pendingOperations.remove(op.getId()); } } }); }
From source file:com.vmware.xenon.common.http.netty.NettyChannelPool.java
License:Open Source License
public void connectOrReuse(NettyChannelGroupKey key, Operation request) { if (request == null) { throw new IllegalArgumentException("request is required"); }//w w w. ja v a 2 s .com if (key == null) { request.fail(new IllegalArgumentException("connection key is required")); return; } try { NettyChannelGroup group = getChannelGroup(key); final NettyChannelContext context = selectContext(request, group); if (context == null) { // We have no available connections, request has been queued return; } // If the connection is open, send immediately if (context.getChannel() != null) { context.setOperation(request); request.complete(); return; } // Connect, then wait for the connection to complete before either // sending data (HTTP/1.1) or negotiating settings (HTTP/2) ChannelFuture connectFuture = this.bootStrap.connect(key.host, key.port); connectFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { Channel channel = future.channel(); if (NettyChannelPool.this.isHttp2Only) { // We tell the channel what its channel context is, so we can use it // later to manage the mapping between streams and operations channel.attr(NettyChannelContext.CHANNEL_CONTEXT_KEY).set(context); // We also note that this is an HTTP2 channel--it simplifies some other code channel.attr(NettyChannelContext.HTTP2_KEY).set(true); waitForSettings(channel, context, request, group); } else { context.setOpenInProgress(false); context.setChannel(channel).setOperation(request); sendAfterConnect(channel, context, request, null); } } else { returnOrClose(context, true); fail(request, future.cause()); } } }); } catch (Throwable e) { fail(request, e); } }
From source file:com.vmware.xenon.common.http.netty.NettyChannelPool.java
License:Open Source License
/** * When using HTTP/2, we have to wait for the settings to be negotiated before we can send * data. We wait for a promise that comes from the HTTP client channel pipeline *//* ww w . j a v a 2 s .c om*/ private void waitForSettings(Channel ch, NettyChannelContext contextFinal, Operation request, NettyChannelGroup group) { ChannelPromise settingsPromise = ch.attr(NettyChannelContext.SETTINGS_PROMISE_KEY).get(); settingsPromise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { // retrieve pending operations List<Operation> pendingOps = new ArrayList<>(); synchronized (group) { contextFinal.setOpenInProgress(false); contextFinal.setChannel(future.channel()).setOperation(request); pendingOps.addAll(group.pendingRequests); group.pendingRequests.clear(); } sendAfterConnect(future.channel(), contextFinal, request, group); // trigger pending operations for (Operation pendingOp : pendingOps) { pendingOp.setSocketContext(contextFinal); pendingOp.complete(); } } else { returnOrClose(contextFinal, true); fail(request, future.cause()); } } }); }
From source file:com.vmware.xenon.common.http.netty.NettyWebSocketRequestHandler.java
License:Open Source License
private void performWebsocketHandshake(final ChannelHandlerContext ctx, FullHttpRequest nettyRequest) { WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(this.handshakePath, null, false);/*from w w w . j a va 2s .c o m*/ this.handshaker = factory.newHandshaker(nettyRequest); if (this.handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { ChannelPromise promise = new DefaultChannelPromise(ctx.channel()); promise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.channel().close(); } ctx.channel().closeFuture().addListener(f -> { for (java.util.Map.Entry<URI, Set<String>> e : NettyWebSocketRequestHandler.this.serviceSubscriptions .entrySet()) { WebSocketService svc = NettyWebSocketRequestHandler.this.webSocketServices .get(e.getKey()); if (svc != null) { deleteServiceSubscriptions(svc); } NettyWebSocketRequestHandler.this.host.stopService(svc); } }); } }); DefaultHttpHeaders responseHeaders = new DefaultHttpHeaders(); CharSequence token = nettyRequest.headers().get(Operation.REQUEST_AUTH_TOKEN_HEADER, null); if (token == null) { String cookie = nettyRequest.headers().get(HttpHeaderNames.COOKIE); if (cookie != null) { token = CookieJar.decodeCookies(cookie).get(AuthenticationConstants.REQUEST_AUTH_TOKEN_COOKIE); } } this.authToken = token == null ? null : token.toString(); this.handshaker.handshake(ctx.channel(), nettyRequest, responseHeaders, promise); } }
From source file:com.vmware.xenon.common.test.websockets.JsWebSocket.java
License:Open Source License
/** * Standard constructor WebSocket(uri) available in JavaScript API * * @param endpointUri Websocket endpoint URI */// w w w .jav a 2 s . c om public JsWebSocket(String endpointUri) throws Exception { URI uri = new URI(endpointUri); String scheme = uri.getScheme() == null ? WS_SCHEME : uri.getScheme(); final String host = uri.getHost() == null ? ServiceHost.LOCAL_HOST : uri.getHost(); final int port; if (uri.getPort() == -1) { if (WS_SCHEME.equalsIgnoreCase(scheme)) { port = 80; } else if (WSS_SCHEME.equalsIgnoreCase(scheme)) { port = 443; } else { port = -1; } } else { port = uri.getPort(); } if (!WS_SCHEME.equalsIgnoreCase(scheme) && !WSS_SCHEME.equalsIgnoreCase(scheme)) { System.err.println("Only WS(S) is supported."); return; } final boolean ssl = WSS_SCHEME.equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } this.group = new NioEventLoopGroup(); // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00. // If you change it to V00, ping is not supported and remember to change // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline. DefaultHttpHeaders headers = new DefaultHttpHeaders(); if (OperationContext.getAuthorizationContext() != null && OperationContext.getAuthorizationContext().getToken() != null) { headers.add(HttpHeaderNames.COOKIE, CookieJar.encodeCookies( Collections.singletonMap(AuthenticationConstants.REQUEST_AUTH_TOKEN_COOKIE, OperationContext.getAuthorizationContext().getToken()))); } final WebSocketClientHandler handler = new WebSocketClientHandler( WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, headers)); Bootstrap b = new Bootstrap(); b.group(this.group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline p = ch.pipeline(); if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc(), host, port)); } p.addLast(new HttpClientCodec(), new HttpObjectAggregator(8192), handler); } }); this.channel = b.connect(uri.getHost(), port).sync().channel(); handler.handshakeFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { try { JsExecutor.executeSynchronously(() -> { if (future.isSuccess()) { if (JsWebSocket.this.onopen != null) { JsWebSocket.this.onopen.call(Context.getCurrentContext(), getParentScope(), JsWebSocket.this, new Object[] { null }); } } else { throw new RuntimeException(future.cause()); } }); } catch (Exception e) { e.printStackTrace(); } } }); }