对基于VOIP业务的对讲有一点了解之后,那我们再来看看要完成一次对讲需要多少状态来表示。大概有下面几种状态:
1.granted:当你向服务器申请讲话的时候,并不是你申请了就一定会成功,因为在一个群组里面能讲话的只能是一个人,如果当前有人在讲话那么你肯定就不能讲了,所以当你申请之后服务器会给一个返回表示是否可以讲话,那么如果服务器返回了granted那么说明你当前可以讲话了。但是如果你收到了grant但是你没有发送语音,那么在几秒之后服务器可能会把你断掉。
2.idle:顾名思义就是空闲的意思,空闲就说明当前没有人在说话。
3.revoke:对于revoke消息有很多种情况,例如你讲话超时服务器会给你返回一个revoke表示你的话语权被剥夺,还有可能是因为别人的优先级比你高所以你也被剥夺了。一般被剥夺之后会有一个被剥夺的原因。
4.deny:deny拒绝,当服务器返回granted的时候表示你可以讲话了,那如果不能讲话的时候返回什么呢,那就是deny了。还有一些其他的情况也会出现deny了,比如服务器设置了你当前是仅听的状态,也就是你的发言被禁了。
5.taken:taken消息表示当前有人要发言了,在收到这个消息之后就可能收到语音了。
这些状态看起来比较简单,但是对于多会话以及网络的影响,就显得不那么简单了。
首先是消息丢失的问题:大家都知道,基于数据业务的对讲使用UDP的居多,因为UDP比较及时。那么相信大家也知道UDP有一个致命的缺点那就是丢包的问题。那大家就会想了如果在传输过程中把消息丢了那该怎么办呢?为此客户端和服务端都做了相应的改进。在服务端那就是连续发同一个消息,例如将granted连续发送5次,如果5次都丢了那说明网络环境真的很不好。服务端的改进可以解决一大部分丢包的问题,但是并不能完全解决,对于接收方如果恰巧就发送消息的时间短网络不好把消息全丢了。但是服务器并不知道你没有收到taken的消息,还是继续给你发语音,那就会出现一长串的语音发送到你。所以这个时候客户端如果只是根据有没有收到taken消息来判断是否要收听是不是有点武断呢,可能真的会丢失信息。可是如果我们用是否收到语音为判断的标准,那么是否会更合理呢,尽管在有的时候可能看不到讲话人的信息,但是总比把语音丢掉比较好吧。所以这个时候可能不仅仅要判断消息还要检测语音的情况来判断是否要播放。
其实是网络乱序:最主要的就是语音消息和控制消息的混乱,例如语音先来控制消息后来,那就会导致客户端的判断错误。
再次对于多会话:对于同一终端,在同一时间只能有一个人说或者一个人听,如果听多个人的讲话,那么就会比较混乱,这个时候就必须要有一个控制的策略。