Search in sources :

Example 6 with ConnectionInfo

use of org.bcos.channel.handler.ConnectionInfo in project web3sdk by FISCO-BCOS.

the class Server method onRemoteMessage.

public void onRemoteMessage(ChannelHandlerContext ctx, Message message) {
    try {
        logger.debug("处理请求: " + message.getSeq());
        ChannelHandlerContext localCtx = null;
        ConnectionPair pair = seq2Connections.get(message.getSeq());
        if (message.getType() == 0x30) {
            // 链上链下二期,需要找到关注该topic的连接
            Short length = (short) message.getData()[0];
            String topic = new String(message.getData(), 1, length - 1);
            Set<ChannelHandlerContext> topicCtxs = new HashSet<ChannelHandlerContext>();
            for (ConnectionInfo connectionInfo : localConnections.getConnections()) {
                if (connectionInfo.getTopics().contains(topic)) {
                    ChannelHandlerContext topicCtx = localConnections.getNetworkConnectionByHost(connectionInfo.getHost(), connectionInfo.getPort());
                    if (topicCtx != null && topicCtx.channel().isActive()) {
                        topicCtxs.add(topicCtx);
                    }
                }
            }
            logger.debug("下发topic:{} 共{}个连接关注该topic", topic, topicCtxs.size());
            if (topicCtxs.isEmpty()) {
                // 找不到连接,错误
                logger.error("找不到可下发的连接,返回错误99");
                message.setType((short) 0x31);
                message.setResult(99);
                ByteBuf out = ctx.alloc().buffer();
                message.writeHeader(out);
                message.writeExtra(out);
                ctx.writeAndFlush(out);
                return;
            }
            // 随机下发
            Random random = new Random();
            Integer index = random.nextInt(topicCtxs.size());
            ChannelHandlerContext target = (ChannelHandlerContext) topicCtxs.toArray()[index];
            logger.debug("下发给 {}:{}", ((SocketChannel) target.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) target.channel()).remoteAddress().getPort());
            localCtx = target;
            if (pair == null) {
                pair = new ConnectionPair();
                pair.localConnection = localCtx;
                pair.remoteConnection = ctx;
                pair.setServer(this);
                pair.setMessage(message);
                seq2Connections.put(message.getSeq(), pair);
                pair.init();
            } else {
                pair.remoteConnection = ctx;
            }
        } else {
            if (pair != null) {
                // 已有这个seq,可能是发送响应或者收到回包消息
                logger.debug("已有seq");
                // 收到来自远端的回包
                localCtx = pair.localConnection;
                if (message.getResult() != 0 && message.getType() == 0x31) {
                    // 链上链下二期错误时,执行retry
                    logger.error("对端返回错误:{},重试", message.getResult());
                    pair.retrySendRemoteMessage();
                    return;
                }
                pair.remoteConnection = ctx;
            } else {
                // 没有这个seq,可能是新发请求或者新收到的push
                // 其他消息(链上链下一期),随机发
                localCtx = localConnections.randomNetworkConnection();
            }
        }
        if (localCtx == null || !localCtx.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 = localCtx.alloc().buffer();
        message.writeHeader(out);
        message.writeExtra(out);
        logger.debug("消息发送至:{}:{}", ((SocketChannel) localCtx.channel()).remoteAddress().getAddress().getHostAddress(), ((SocketChannel) localCtx.channel()).remoteAddress().getPort());
        localCtx.writeAndFlush(out);
    } catch (Exception e) {
        logger.error("系统错误", e);
    }
}
Also used : SocketChannel(io.netty.channel.socket.SocketChannel) Random(java.util.Random) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ConnectionInfo(org.bcos.channel.handler.ConnectionInfo) ByteBuf(io.netty.buffer.ByteBuf) UnsupportedEncodingException(java.io.UnsupportedEncodingException) HashSet(java.util.HashSet)

Aggregations

UnsupportedEncodingException (java.io.UnsupportedEncodingException)6 ConnectionInfo (org.bcos.channel.handler.ConnectionInfo)6 SocketChannel (io.netty.channel.socket.SocketChannel)4 ByteBuf (io.netty.buffer.ByteBuf)3 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)3 ArrayList (java.util.ArrayList)3 Timeout (io.netty.util.Timeout)2 TimerTask (io.netty.util.TimerTask)2 HashSet (java.util.HashSet)2 ChannelResponse (org.bcos.channel.dto.ChannelResponse)2 ChannelConnections (org.bcos.channel.handler.ChannelConnections)2 Random (java.util.Random)1 ChannelMessage (org.bcos.channel.dto.ChannelMessage)1 ChannelMessage2 (org.bcos.channel.dto.ChannelMessage2)1 Message (org.bcos.channel.handler.Message)1