回顾
上一篇文章主要带大家一起阅读了添加发布者与添加订阅者命令的执行过程,今天就继续带大家从demo入手,分析发布者发布数据以及订阅者接收数据相关流程
Demo
ini
public static void main(String[] args)
{
final String channel = "aeron:ipc";
final String message = "my message";
final IdleStrategy idle = new SleepingIdleStrategy();
final UnsafeBuffer unsafeBuffer = new UnsafeBuffer(ByteBuffer.allocate(256));
try (MediaDriver driver = MediaDriver.launch();
Aeron aeron = Aeron.connect();
Subscription sub = aeron.addSubscription(channel, 10);
Publication pub = aeron.addPublication(channel, 10))
{
while (!pub.isConnected())
{
idle.idle(); // 简单理解为阻塞即可
}
unsafeBuffer.putStringAscii(0, message);
System.out.println("sending:" + message);
while (pub.offer(unsafeBuffer) < 0) // 发布数据
{
idle.idle();
}
FragmentHandler handler = (buffer, offset, length, header) ->
System.out.println("received:" + buffer.getStringAscii(offset));
while (sub.poll(handler, 1) <= 0) // 接受数据
{
idle.idle();
}
}
}
pub数据
上面就是发布者发布数据的流程,可以看到,最终是把数据写入到底层的termBuffer里,那么数据是在哪里被真正发送出去的呢?
不知道大家是否还记得分析MediaDriver的时候曾提过Reciver线程与Sender线程,故名思义,一个负责接受数据,一个负责发送数据。
查看send线程执行流程如下:
可以看到Sender线程会遍历当前所有的newWorkPublication,调用起send方法进行数据发送,底层其实是调用nio的相关api进行数据发送。
poll数据
poll数据的流程看起来比较简单,其实就是不断的从对应的buffer里获取数据,然后调用自定义的FragmentHandler进行数据的解析,那对应的buffer里的数据是从哪里获取的呢?答案当然是MediaDriver里的Receiver线程做的,其处理流程如下:
可以看到底层其实也是通过nio的相关方法进行数据获取。
小结
本篇文章主要带大家一起阅读了下Aeron的数据发送和接收相关流程,aeron的内部很多机制,都是基于发布与订阅功能实现的,因此,理解相关流程还是很重要的,后面将会为大家代码AeronArchive与replay相关的流程分析。