Search in sources :

Example 41 with SocketChannel

use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.

the class Service method asyncSendEthereumMessage.

public void asyncSendEthereumMessage(EthereumRequest request, EthereumResponseCallback callback) {
    logger.debug("处理Ethereum请求: " + request.getMessageID());
    Boolean sended = false;
    EthereumMessage ethereumMessage = new EthereumMessage();
    ethereumMessage.setSeq(request.getMessageID());
    ethereumMessage.setResult(0);
    ethereumMessage.setType((short) 0x12);
    ethereumMessage.setData(request.getContent().getBytes());
    // 选取发送节点
    try {
        ChannelConnections fromChannelConnections = allChannelConnections.get(orgID);
        if (fromChannelConnections == null) {
            // 没有找到对应的链
            // 返回错误
            logger.error("没有找到本机构:{}", orgID);
            throw new Exception("未找到本机构");
        }
        ChannelHandlerContext ctx = fromChannelConnections.randomNetworkConnection();
        ByteBuf out = ctx.alloc().buffer();
        ethereumMessage.writeHeader(out);
        ethereumMessage.writeExtra(out);
        seq2Callback.put(request.getMessageID(), callback);
        if (request.getTimeout() > 0) {
            // ethereum名字可能会搞混,换成channel
            final EthereumResponseCallback callbackInner = callback;
            callback.setTimeout(timeoutHandler.newTimeout(new TimerTask() {

                EthereumResponseCallback _callback = callbackInner;

                @Override
                public void run(Timeout timeout) throws Exception {
                    // 处理超时逻辑
                    _callback.onTimeout();
                }
            }, request.getTimeout(), TimeUnit.MILLISECONDS));
        }
        ctx.writeAndFlush(out);
        logger.debug("发送Ethereum消息至 " + ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress() + ":" + ((SocketChannel) ctx.channel()).remoteAddress().getPort() + " 成功");
        sended = true;
    } catch (Exception e) {
        logger.error("系统错误", e);
        EthereumResponse response = new EthereumResponse();
        response.setErrorCode(-1);
        response.setErrorMessage("系统错误");
        response.setContent("");
        response.setMessageID(request.getMessageID());
        if (callback.getTimeout() != null) {
            callback.getTimeout().cancel();
        }
        callback.onResponse(response);
    }
}
Also used : ChannelConnections(org.bcos.channel.handler.ChannelConnections) SocketChannel(io.netty.channel.socket.SocketChannel) TimerTask(io.netty.util.TimerTask) Timeout(io.netty.util.Timeout) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) EthereumResponse(org.bcos.channel.dto.EthereumResponse) UnsupportedEncodingException(java.io.UnsupportedEncodingException) EthereumMessage(org.bcos.channel.dto.EthereumMessage)

Example 42 with SocketChannel

use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.

the class ChannelConnections method startListen.

public void startListen(Integer port) {
    if (running) {
        logger.debug("服务已启动");
        return;
    }
    logger.debug("初始化connections listen");
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    final ChannelConnections selfService = this;
    final ThreadPoolTaskExecutor selfThreadPool = threadPool;
    try {
        serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {

            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                KeyStore ks = KeyStore.getInstance("JKS");
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                Resource keystoreResource = resolver.getResource(getClientKeystorePath());
                Resource caResource = resolver.getResource(getCaCertPath());
                ks.load(keystoreResource.getInputStream(), getKeystorePassWord().toCharArray());
                /*
                	 * 每次连接使用新的handler
                	 * 连接信息从socketChannel中获取
                	 */
                ChannelHandler handler = new ChannelHandler();
                handler.setConnections(selfService);
                handler.setIsServer(true);
                handler.setThreadPool(selfThreadPool);
                SslContext sslCtx = SslContextBuilder.forServer((PrivateKey) ks.getKey("client", getClientCertPassWord().toCharArray()), (X509Certificate) ks.getCertificate("client")).trustManager(caResource.getFile()).build();
                ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()), new LengthFieldBasedFrameDecoder(1024 * 1024 * 4, 0, 4, -4, 0), new IdleStateHandler(idleTimeout, idleTimeout, idleTimeout, TimeUnit.MILLISECONDS), handler);
            }
        });
        ChannelFuture future = serverBootstrap.bind(port);
        future.get();
        running = true;
    } catch (Exception e) {
        logger.error("系统错误", e);
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) SocketChannel(io.netty.channel.socket.SocketChannel) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) LoggingHandler(io.netty.handler.logging.LoggingHandler) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) PathMatchingResourcePatternResolver(org.springframework.core.io.support.PathMatchingResourcePatternResolver) ResourcePatternResolver(org.springframework.core.io.support.ResourcePatternResolver) PrivateKey(java.security.PrivateKey) Resource(org.springframework.core.io.Resource) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) EventLoopGroup(io.netty.channel.EventLoopGroup) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) ThreadPoolTaskExecutor(org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor) PathMatchingResourcePatternResolver(org.springframework.core.io.support.PathMatchingResourcePatternResolver) LengthFieldBasedFrameDecoder(io.netty.handler.codec.LengthFieldBasedFrameDecoder) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) SslContext(io.netty.handler.ssl.SslContext)

Example 43 with SocketChannel

use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.

the class ChannelHandler method channelRead.

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
    Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
    final ChannelHandlerContext ctxF = ctx;
    final ByteBuf in = (ByteBuf) msg;
    logger.trace("接收消息,来自" + host + ":" + port + " in:" + in.readableBytes());
    logger.trace("threadPool:{}", threadPool == null);
    try {
        if (threadPool == null) {
            connections.onReceiveMessage(ctx, in);
        } else {
            threadPool.execute(new Runnable() {

                @Override
                public void run() {
                    connections.onReceiveMessage(ctxF, in);
                }
            });
        }
    } catch (RejectedExecutionException e) {
        logger.error("线程池已满,拒绝请求", e);
    }
}
Also used : SocketChannel(io.netty.channel.socket.SocketChannel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 44 with SocketChannel

use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.

the class ChannelHandler method channelActive.

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    try {
        // 已连上,获取ip信息
        String host = ((SocketChannel) ctx.channel()).remoteAddress().getAddress().getHostAddress();
        Integer port = ((SocketChannel) ctx.channel()).remoteAddress().getPort();
        logger.debug("已成功连接[" + host + "]:[" + String.valueOf(port) + "]," + String.valueOf(ctx.channel().isActive()));
        if (isServer) {
            logger.debug("server接收新连接: {}:{}", host, port);
            // 将此新连接增加到connections
            ConnectionInfo info = new ConnectionInfo();
            info.setHost(host);
            info.setPort(port);
            connections.getConnections().add(info);
            connections.setNetworkConnectionByHost(info.getHost(), info.getPort(), ctx);
            connections.getCallback().onConnect(ctx);
        } else {
            // 更新ctx信息
            ChannelHandlerContext connection = connections.getNetworkConnectionByHost(host, port);
            if (connection != null && connection.channel().isActive()) {
                logger.debug("连接已存在且有效 关闭重连: {}:{}", host, port);
                ctx.channel().disconnect();
                ctx.channel().close();
            } else {
                logger.debug("client成功连接 {}:{}", host, port);
                connections.setNetworkConnectionByHost(host, port, ctx);
                connections.getCallback().onConnect(ctx);
            }
        }
    } catch (Exception e) {
        logger.error("系统错误", e);
    }
}
Also used : SocketChannel(io.netty.channel.socket.SocketChannel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 45 with SocketChannel

use of io.netty.channel.socket.SocketChannel in project web3sdk by FISCO-BCOS.

the class Server method onLocalMessage.

public void onLocalMessage(ChannelHandlerContext ctx, Message message) {
    try {
        logger.debug("处理来自SDK请求: " + message.getSeq());
        ChannelHandlerContext remoteCtx = null;
        ConnectionPair pair = seq2Connections.get(message.getSeq());
        if (pair != null) {
            // 已有这个seq,发往远端的响应
            logger.debug("已有seq");
            // 发送到远端的响应
            remoteCtx = pair.remoteConnection;
            if (message.getType() != 0x31) {
                pair.localConnection = ctx;
            }
            ByteBuf out = remoteCtx.alloc().buffer();
            message.writeHeader(out);
            message.writeExtra(out);
            logger.debug("消息发送至:{}:{}", ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
            remoteCtx.writeAndFlush(out);
        } else {
            pair = new ConnectionPair();
            pair.localConnection = ctx;
            pair.setServer(this);
            pair.setMessage(message);
            // 本地发往远程的消息,如果是链上链下,需要按给定的nodeID发
            if (message.getType() == 0x20 || message.getType() == 0x21) {
                // 获取nodeID
                logger.debug("链上链下消息一期 指定目的地");
                if (message.getData().length < 256) {
                    logger.error("错误的channel消息 长度不足256:{}", message.getData().length);
                }
                // 获取nodeID对应的连接,检查可用性
                String nodeID = new String(message.getData(), 128, 128);
                logger.debug("转发至:{}", nodeID, message.getData());
                for (ConnectionInfo conn : remoteConnections.getConnections()) {
                    if (conn.getNodeID().equals(nodeID)) {
                        remoteCtx = remoteConnections.getNetworkConnectionByHost(conn.getHost(), conn.getPort());
                        pair.remoteConnection = remoteCtx;
                        break;
                    }
                }
                if (remoteCtx == null || !remoteCtx.channel().isActive()) {
                    // 找不到连接,错误
                    logger.error("发送连接异常,返回错误99");
                    if (message.getType() == 0x20 || message.getType() == 0x21) {
                        message.setType((short) 0x21);
                    } else {
                        message.setType((short) 0x31);
                    }
                    message.setResult(99);
                    ByteBuf out = ctx.alloc().buffer();
                    message.writeHeader(out);
                    message.writeExtra(out);
                    ctx.writeAndFlush(out);
                    return;
                }
                ByteBuf out = remoteCtx.alloc().buffer();
                message.writeHeader(out);
                message.writeExtra(out);
                logger.debug("消息发送至:{}:{}", ((SocketChannel) remoteCtx.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) remoteCtx.channel()).remoteAddress().getPort());
                remoteCtx.writeAndFlush(out);
                pair.init();
            } else {
                logger.debug("其它消息,使用ConnectionPair逻辑");
                pair.setRemoteChannelConnections(remoteConnections);
                List<ConnectionInfo> remoteConnectionInfos = new ArrayList<ConnectionInfo>();
                remoteConnectionInfos.addAll(remoteConnections.getConnections());
                pair.setRemoteConnectionInfos(remoteConnectionInfos);
                seq2Connections.put(message.getSeq(), pair);
                pair.init();
                pair.retrySendRemoteMessage();
            }
        }
    } catch (Exception e) {
        logger.error("系统错误", e);
    }
}
Also used : SocketChannel(io.netty.channel.socket.SocketChannel) ArrayList(java.util.ArrayList) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ConnectionInfo(org.bcos.channel.handler.ConnectionInfo) ByteBuf(io.netty.buffer.ByteBuf) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Aggregations

SocketChannel (io.netty.channel.socket.SocketChannel)84 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)43 ChannelPipeline (io.netty.channel.ChannelPipeline)37 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)33 Bootstrap (io.netty.bootstrap.Bootstrap)32 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)32 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)30 ChannelFuture (io.netty.channel.ChannelFuture)28 EventLoopGroup (io.netty.channel.EventLoopGroup)28 Channel (io.netty.channel.Channel)20 SslContext (io.netty.handler.ssl.SslContext)20 LengthFieldBasedFrameDecoder (io.netty.handler.codec.LengthFieldBasedFrameDecoder)16 IOException (java.io.IOException)15 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)14 InetSocketAddress (java.net.InetSocketAddress)14 LoggingHandler (io.netty.handler.logging.LoggingHandler)12 ByteBuf (io.netty.buffer.ByteBuf)11 SslHandler (io.netty.handler.ssl.SslHandler)9 SSLEngine (javax.net.ssl.SSLEngine)8 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)7