将全局map拆分成多个(数量:CHANNEL_MAP_NUM),以减小同步锁压力,提高性能

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;

/**
 * websocket 上下文
 */
public class WebSocketContext {

    private static final int CHANNEL_MAP_NUM = 256;

    private static final String USER_ID = "userId";

    public static final AttributeKey<String> ATTR_KEY_USER_ID = AttributeKey.valueOf(USER_ID);

    /**
     * 将全局map拆分成多个(数量:CHANNEL_MAP_NUM),以减小同步锁压力,提高性能
     */
    private static final Map<Integer,Map<String,Channel>> ALL_CHANNEL_MAP = new ConcurrentHashMap<>(CHANNEL_MAP_NUM);

    static {
        //初始化ALL_CHANNEL_MAP
        IntStream.range(0,CHANNEL_MAP_NUM-1).forEach(x->ALL_CHANNEL_MAP.put(x,new ConcurrentHashMap<>()));
    }

    public static void addChannel(String userId, Channel channel){
        Attribute<String> channelAttrUserId = channel.attr(ATTR_KEY_USER_ID);
        channelAttrUserId.set(userId);
        getChannelMap(userId).put(userId,channel);
    }

    public static Channel getChannel(String userId){
        return getChannelMap(userId).get(userId);
    }

    public static void removeChannel(String userId){
        getChannelMap(userId).remove(userId);
    }

    /**
     * 根据用户ID找到相应的Channel Map
     * @param userId userId
     * @return channel map
     */
    private static Map<String,Channel> getChannelMap(String userId){
        return ALL_CHANNEL_MAP.get(getChannelMapIndex(userId));
    }

    /**
     * 根据用户ID获取index = hash(userId) % CHANNEL_MAP_NUM
     * @param userId 用户ID
     * @return channel map index
     */
    private static int getChannelMapIndex(String userId){
        return userId.hashCode() % CHANNEL_MAP_NUM;
    }

    //todo 如性能差sendMsg及各种重载可做优化
    public static void sendMsg(String usrId,byte[] data){
        sendMsg(getChannel(usrId),data);
    }

    public static void sendMsg(Channel channel,byte[] data){
        if (channel == null) {
            return;
        }
        ByteBuf buffer = channel.alloc().buffer(data.length);
        channel.writeAndFlush(new BinaryWebSocketFrame(buffer.writeBytes(data)));
    }

    public static void sendMsg(Collection<String> users, byte[] data){
        for(String userId:users){
            sendMsg(userId,data);
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值