All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.godmao.mqbroker.handler.MultipleMessageHandler Maven / Gradle / Ivy

There is a newer version: 0.2.7.RELEASE
Show newest version
package com.godmao.mqbroker.handler;

import com.godmao.mqbroker.Broker;
import com.godmao.mqbroker.Static;
import com.godmao.mqbroker.message.MultipleMessage;
import com.godmao.netty.channel.ChannelService;
import io.netty.channel.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class MultipleMessageHandler extends SimpleChannelInboundHandler {
    private final Broker connect;

    public MultipleMessageHandler(Broker connect) {
        this.connect = connect;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MultipleMessage.Request msg) {
        final List datas = msg.getDatas();
        final List topics = msg.getTopics();
        final byte model = msg.getModel();
        final long delay = msg.getDelay() > 0 ? msg.getDelay() - System.currentTimeMillis() : -1;
        final boolean LOADBALANCE = model == 1;


        final Runnable runnable = () -> {
            //
            final Map>> matcheGroup = new HashMap<>();
            for (Channel _channel : connect.getChannelService()) {
                if (!_channel.isActive()) {
                    continue;
                }
                final Boolean _authorization = _channel.attr(Static.AUTHORIZATION).get();
                if (null == _authorization || !_authorization) {
                    continue;
                }
                final Object _channelId = _channel.attr(ChannelService.CHANNELID).get();
                final Set _topics = _channel.attr(Static.TOPIC).get();
                final Map> _indexGroup = matcheGroup.computeIfAbsent(_channelId, k -> new HashMap<>());
                for (int i = 0; i < topics.size(); i++) {
                    final String topic = topics.get(i);
                    if (_topics.contains(topic)) {
                        final Set _channels = _indexGroup.computeIfAbsent(i, k -> new HashSet<>());
                        _channels.add(_channel);
                    }
                }
            }

            final Map channelServerMessageMultiwayMap = new HashMap<>();
            for (Map.Entry>> _entry : matcheGroup.entrySet()) {
                final Object _key = _entry.getKey();
                final Map> _indexGroup = _entry.getValue();
                final Set channels = new HashSet<>();
                for (Map.Entry> _indexEntry : _indexGroup.entrySet()) {
                    final Integer _index = _indexEntry.getKey();
                    final String _topic = topics.get(_index);
                    final Set _channels = _indexEntry.getValue();
                    if (LOADBALANCE && _channels.size() > 1) {
                        // 是负载均衡模式 并且有多个会话
                        final int _key_counter_hash = (_key + _topic).hashCode();
                        final AtomicLong _counter = Static.HASH_COUNTERS.computeIfAbsent(_key_counter_hash, k -> new AtomicLong());
                        final int flag = Math.abs((int) (_counter.incrementAndGet() % (long) _channels.size()));
                        final Channel _channel = (Channel) _channels.toArray()[flag];
                        channels.add(_channel);
                    } else {
                        // 广播模式
                        channels.addAll(_channels);
                    }
                    //
                    for (Channel _channel : channels) {
                        final MultipleMessage.Response multipleServerMessage = channelServerMessageMultiwayMap.computeIfAbsent(_channel, k -> new MultipleMessage.Response(new ArrayList<>(), new ArrayList<>()));
                        multipleServerMessage.getTopics().add(_topic);
                        multipleServerMessage.getDatas().add(datas.get(Math.min(datas.size() - 1, _index)));
                    }
                }
            }

            //
            for (Map.Entry channelServerMessageMultiwayEntry : channelServerMessageMultiwayMap.entrySet()) {
                final Channel _channel = channelServerMessageMultiwayEntry.getKey();
                final MultipleMessage.Response _multiple_serverMessage = channelServerMessageMultiwayEntry.getValue();

                connect.send(
                        _multiple_serverMessage,
                        _channel,
                        0,
                        0
                );
            }
        };

        if (delay > 0) {
            ctx.channel().eventLoop().schedule(runnable, delay, TimeUnit.MILLISECONDS);
        } else {
            runnable.run();
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy