我想要实现两部安卓客户端的实时语音通讯,安卓客户端都在内网,因此需要一外网pc做数据的中转服务器,安卓语音发送端通过audiotrack录制PCM音频数据并实时发送到服务器,服务器接收数据并不断读入一个缓冲区,开启另一个线程循环读取缓冲区的数据同时将数据发送到另一个安卓客户端,问题就在于服务器的缓冲区要怎么做?怎么保证缓冲区的数据同时被两个线程操作时的有序稳定 求大神指教,假设网络良好,不考虑网络波动带来的数据处理问题。
关键是语音流. 对队列也比较赞同. 不过考虑并发多线程问题. 缓冲区 内部划分应该分: 发送区, 资源区, 接受区. 对消息进行编号. 例如2s一个语音段, 发送成功就成功, 不然丢弃. 编号之后, 可以同时并发发送. 发送区进行资源锁定, 进入server 资源区后解锁. 接受区也是一样的, 维护一个顺序索引. 按顺序发送资源区给接收端. 如果丢包你, 怎么处理. 就是语音丢失闹 . 后面再有也不要你. 锁定之后就好. 其实生产--消费者思路. 至于实现, 如何并发, 并发 ,对外封装调用.
两个线程操作有序稳定,那一个时间只能由一个线程操作,加锁
线程为什么要循环读缓冲区的数据呢?这个我没太明白
这种通信类似于消息队列,服务器有一个类似消息中转器的队列就行了,先进先出,实现转发
不知道你是不是要实现这个
服务器的缓冲区独立使用,也就是指负责向里面循环写数据,满了就覆盖前面的数据。
额外两个线程操作各自独立的读指针位置!读取各自实时的数据,互不相干。
ps:是不是理解错题意了?
建议服务器启动时申请好缓冲区,避免锁定,解锁及内存申请、释放,可使用静态数组进行存储。
m_pBuffer[100][4000]
100为缓冲区最多存储100条数据,4000为消息内容区,可以再细分2数据长度+3998数据内容。
从socket读取一次,向m_pBuffer存一条,m_nWriteIndex++,在这注意判断m_nWriteIndex边界值,m_nWriteIndex要小于101,m_nWriteIndex 与m_nReadIndex相等,则m_nReadIndex必须++,意味着接收线程快,发送线程慢,导致数据缓冲较多,导致丢帧。
读的时候简单啦,只需要判断m_nReadIndex 小于 m_nWriteIndex,且m_nReadIndex要小于101。m_nReadIndex 等于 m_nWriteIndex则表示没有新数据。
拙见,没有高级应用,仅供参考。
可以使用生产者-消费者模式,使用一个优先级队列存储数据,为什么用优先级队列呢?因为你需要对发来的数据包含时间戳信息,并且按照时间排序。这样也回答你如何有序的问题。
在读、写的时候,对队列加锁。你可以为配对的两个客户端建立一个独立的队列,这样当有很多客户端各自和对方通讯的时候,每个队列互相之间不用干扰。在局域网内,延迟应该是很小的,所以应该有很好的性能。
服务器接收到数据直接转发不行么
参考苏小喵说的
说白了就是一个RingBuffer
为什么不想PC一样,服务器只是用来告诉两个安卓客户端对方的地址,然后安卓客户端直连,就像P2P打洞。即减轻服务器负担,又提高两个安卓客户端的效率。除非需要在服务器记录双方的通话内容。
我做过安卓上的实时对讲通信3G环境下0.2秒左右的延迟,有疑问可联系我qq 22900104, 服务端直接中转RTP即可,不用缓存数据。
不知道怎么实现的? 我之前是使用 public static byte[] 类型的唤醒队列,
不然在别的类中访问不到缓冲区,所以我只能这么弄,我感觉会出问题的,不知道你是怎么处理的?
希望能分享一下你的思路,感谢,愿上帝赐福与你,