1.2K Star 8.1K Fork 2.2K

GVP轨迹 / J-IM

 / 详情

imClientChannelContext = jimClient.connect(serverNode); 返回为空

Backlog
Opened this issue  
2021-01-21 08:56

我觉得我找到了jim-client的一个bug,但是不知道该怎么改。

public ImClientChannelContext connect(Node serverNode, Integer timeout) throws Exception {
	log.warn("J-IM client connect");
	tioClient = new TioClient((ClientTioConfig) imClientConfig.getTioConfig());
	ClientChannelContext clientChannelContext = tioClient.connect(serverNode, imClientConfig.getBindIp(), imClientConfig.getBindPort(), timeout);
	if(Objects.nonNull(clientChannelContext)){
		log.warn("J-IM client connected success at serverAddress:[{}], bind localAddress:[{}]", serverNode.toString(), imClientConfig.toBindAddressString());
		return (ImClientChannelContext)clientChannelContext.get(ImConst.Key.IM_CHANNEL_CONTEXT_KEY);
	}
	return null;
}

里面的 clientChannelContext.get(ImConst.Key.IM_CHANNEL_CONTEXT_KEY);
这一行 很大的概率返回null

也就是 工程中
channelContext.set(Key.IM_CHANNEL_CONTEXT_KEY, imChannelContext); 执行的顺序 在 clientChannelContext.get(ImConst.Key.IM_CHANNEL_CONTEXT_KEY); 之后,我看到里面操作的是一个map,
private final MapWithLock<String, Object> props = new MapWithLock(new HashMap(8));

应该是多线程导致的

Comments (5)

lanxia created任务
lanxia set related repository to 轨迹/J-IM
lanxia changed description
Expand operation logs

"不是很大的概率" 是 有一定的概率,跟机器有关系。

再往下跟了一下,我想问题应该在这里

	CountDownLatch countDownLatch = new CountDownLatch(1);
	attachment.setCountDownLatch(countDownLatch);
	asynchronousSocketChannel.connect(inetSocketAddress, attachment, this.clientTioConfig.getConnectionCompletionHandler());
	boolean f = countDownLatch.await((long)realTimeout, TimeUnit.SECONDS);
	if (f) {
		return attachment.getChannelContext();
	} else {
		log.error("countDownLatch.await(realTimeout, TimeUnit.SECONDS) 返回false ");
		return attachment.getChannelContext();
	}

这里有一个睡眠,但是睡的不够

这里有好几个线程,貌似没有做线程的同步

这里有好几个线程,貌似没有做线程的同步

@lanxia 或者说同步做的不好

最后解决了,底层不敢改,只敢改上层的东西。
重写写了一个类 WJimCient(里面基本复制的JimClient中的内容)

/***
 * auth: robin
 * date: 2021/01/21
 * 这里基本复制的JimClient,没直接用JimClient的原因是,
 * clientChannelContext.get("im_channel_context_key") 很大的概率会返回null,
 * 因为里面有个map,赋值是通过多线程来完成的,如果另一个线程没有赋值的话,这里得到的就是null
 *
 */

public class WJimClient {
    private static Logger log = LoggerFactory.getLogger(JimClient.class);
    private TioClient tioClient = null;
    private ImClientConfig imClientConfig;

    public WJimClient(ImClientConfig imClientConfig) {
        this.imClientConfig = imClientConfig;
    }

    public ImClientChannelContext connect(Node serverNode) throws Exception {
        return this.connect(serverNode, (Integer)null);
    }

    public ImClientChannelContext connect(Node serverNode, Integer timeout) throws Exception {
        log.warn("J-IM client connect");
        this.tioClient = new TioClient((ClientTioConfig)this.imClientConfig.getTioConfig());
        ClientChannelContext clientChannelContext = this.tioClient.connect(serverNode, this.imClientConfig.getBindIp(), this.imClientConfig.getBindPort(), timeout);
        if (Objects.nonNull(clientChannelContext)) {
            log.warn("J-IM client connected success at serverAddress:[{}], bind localAddress:[{}]", serverNode.toString(), this.imClientConfig.toBindAddressString());
            ImClientChannelContext t_rtnContext = (ImClientChannelContext)clientChannelContext.get("im_channel_context_key");
            int t_maxCount = 200; //最大循环次数,实际测试中只循环了一次
            while (null == t_rtnContext
            && t_maxCount > 0){//这里是在等待另一个线程写入
                Thread.sleep(50);
                t_rtnContext = (ImClientChannelContext)clientChannelContext.get("im_channel_context_key");
                t_maxCount--;
            }
            System.out.println("robin:count:"+(200-t_maxCount));
            return t_rtnContext;
        } else {
            return null;
        }
    }

    public void stop() {
        this.tioClient.stop();
    }
}

Sign in to comment

Status
Assignees
Milestones
Pull Requests
Successfully merging a pull request will close this issue.
Branches
Planed to start   -   Planed to end
-
Top level
Priority
参与者(1)
60075 lanxiaziyi oschina 1609138580
Java
1
https://git.oschina.net/xchao/j-im.git
git@git.oschina.net:xchao/j-im.git
xchao
j-im
J-IM

Search