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

com.godmao.mqbroker.handler.SingleMessageHandler 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.SingleMessage;
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 SingleMessageHandler extends SimpleChannelInboundHandler {
    private final Broker connect;

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

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, SingleMessage.Request msg) {
        final byte[] _data = msg.getData();
        final byte model = msg.getModel();
        final long delay = msg.getDelay();
        final String _topic = msg.getTopic();

        final Runnable runnable = () -> {
            // key channelid value channel(匹配到有主题的channel)
            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 Set _topics = _channel.attr(Static.TOPIC).get();
                if (!_topics.contains(_topic)) {
                    continue;
                }
                final Object _channelId = _channel.attr(ChannelService.CHANNELID).get();
                final List _channels = matcheGroup.getOrDefault(_channelId, new ArrayList<>());
                _channels.add(_channel);
                matcheGroup.put(_channelId, _channels);
            }

            if (!matcheGroup.isEmpty()) {
                //
                final boolean LOADBALANCE = model == 1;
                final Set channels = new HashSet<>();
                //
                for (Map.Entry> _channelsEntry : matcheGroup.entrySet()) {
                    final Object _key = _channelsEntry.getKey();
                    final List _channels = _channelsEntry.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 = _channels.get(flag);
                        channels.add(_channel);
                    } else {
                        // 广播模式
                        channels.addAll(_channels);
                    }
                }

                //
                final SingleMessage.Response response = new SingleMessage.Response(_topic, _data);
                for (final Channel channel : channels) {
                    connect.send(response, channel, 0, 0);
                }
            }
        };

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy