本文章主要讲述KaaClient是如何向operationServer发送和接受消息。operationServer是处理核心业务的服务(configuration、event、log、notification、profile)。
KaaClient初始化operationsChannel,添加到channelManager中管理
KaaClient在启动的时候会初始化bootstrapChannel和operationsChannel,并将其加入到channelManager中管理。也就是说channelManager可以同时管理者两个channel, 下面我仅针对operationChannel讲解。
// 初始化operationChannel
KaaDataChannel operationsChannel = new DefaultOperationTcpChannel(kaaClientState, failoverManager);
// 将operationChannel加入到channelManager
channelManager.addChannel(operationsChannel);
channelManager会做如下事情:
-
将operationChannel添加到自己的全局channelList中,并对operationChannel创建线程。
channels.add(channel); // 添加到channelList中 startWorker(channel); // 创建线程,并启动
建立消息通道
-
channelManger为operationChannel添加可用的operationServer信息。
// serve中包含operarionServer的服务器信息, IP、Port、通信用的公私钥信息等等 channel.setServer(server);
-
DefaultOperationTcpChannel根据server信息,创建Kaa Client和Operation Server的socket连接
// 创建Executor executor = createExecutor(); // 执行打开连接任务 executor.schedule(openConnectionTask, retryPeriod, TimeUnit.MILLISECONDS); // 创建socket连接 socket = createSocket(currentServer.getHost(), currentServer.getPort());
向OperationServer发送消息
-
创建发送请求线程
// 为operationChannel创建消息请求线程 SyncWorker worker = new SyncWorker(channel); // 为operationChannel创建对应的消息阻塞队列 syncTaskQueueMap.put(channel.getId(), new LinkedBlockingQueue<SyncTask>()); // 将operationChannel线程放进syncWorkers中,对线程进行管理 syncWorkers.put(channel.getId(), worker); // 启动线程 worker.start();
-
启动线程,处理阻塞队列
// 获取operationChannel的阻塞队列 BlockingQueue<SyncTask> taskQueue = syncTaskQueueMap.get(channel.getId()); // 从阻塞队列中获取任务,如果没有任务会一直阻塞在这里等待任务加入 SyncTask task = taskQueue.take(); // 向operationServer发送消息 channel.syncAck(task.getTypes());
看到这里,当Kaa Client要向operationServer发请求的时候,只要向operationChannel的阻塞队列放SyncTask任务即可。
接受OperationServer消息
-
operationChannel中启动socket消息读取线程
readTaskFuture = executor.submit(new SocketReadTask(socket));
(1) SocketReadTask 线程会读取来自服务端的socket消息
// 获取socket通道消息,这里是阻塞的 int size = readTaskSocket.getInputStream().read(buffer);
(2) socket消息转成 MQTT协议, 并广播给各个listener
// 接收到消息,将TCP字节流转成 mqtt协议, 并通知各个listener: connAckListener、kaaSyncResponseListener、pingResponseListener、 disconnectListener messageFactory.getFramer().pushBytes(Arrays.copyOf(buffer, size)); // 广播消息 for(MqttFramelistener listener : listeners) { listener.onMqttFrame(frame); }
KaaClient和operationServer通信是基于MQTT协议的, MQTT是物联网专用协议, 其实他是基于TCP协议在应用层的一个封装。