I. 注册回调

RegisterAgent类

在TransactionClient Fail/Success的回调中, 调用RegisterAgentListener的Register Fail/Sucess接口

public class RegisterAgent implements TransactionClientListener, SubscriberDialogListener {

  RegisterAgentListener listener;
public RegisterAgent(...RegisterAgentListener listener, ...) {} public void onTransSuccessResponse(TransactionClient ransaction, Message resp) {
listener.onUaRegistrationSuccess(this, target, contact, result);
} public void onTransFailureResponse(TransactionClient, Message resp) {
listener.onUaRegistrationFailure(this, target, contact, result);
} public void onTransTimeout(TransactionClient transaction) {
listener.onUaRegistrationFailure(this, target, contac, "Timeout");
listener.onUaRegistrationSuccess(this, target, contac, "Timeout");
}
}

TransactionClient类/--->SipProviderListener

1. extends Transaction

public abstract class Transaction implements SipProviderListener, TimerListener {
public void onReceivedMessage(SipProvider provider, Message msg){}
}

2. TransactionClient类

在Transaction Fail/Success(实际的SipProvider回调)的回调中, 调用TransactionClient的 Fail/Sucess接口

public class TransactionClient extends Transaction {
TransactionClientListener transaction_listener; public TransactionClient(SipProvider sip_provider, Message req, TransactionClientListener listener) {
super(sip_provider);
request = new Message(req);
init(listener, request.getTransactionId()); //this.transaction_listener = listener;
}
//实际上的SipProvider回调
public void onReceivedMessage(SipProvider provider, Message msg) {
transaction_listener.onTransSuccessResponse(this, msg);
transaction_listener.onTransFailureResponse(this, msg);
} pulic void onTimeout(Timer to) {
//和超时相关的transaction_listener回调
}
}

所以, SipProviderListener又是哪个对象触发的呢?


II. 来电回调

我真的太机智了, Sipdroid回调嵌套得很深, 从回调处理顺藤摸瓜找到回调触发很复杂, 找着找着就迷失在代码里. 倒不如来个crash, Boom! Runtime Exception blablabla... 然后系统就寄几把函数调用堆栈打印出来了蛤蛤蛤~

12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: UA: onCallAccepted()
12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: UA: ACCEPTED/CALL
12-19 10:43:03.284 26271-26297/com.hik.visapp I/System.out: SipProvider: WARNING: Error handling a new incoming message
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: java.lang.RuntimeException: Tried to costruct a new Parser with a null String
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.tools.Parser.<init>(Parser.java:64)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sdp.SdpParser.<init>(SdpParser.java:39)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sdp.SessionDescriptor.<init>(SessionDescriptor.java:205)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.sipdroid.sipua.UserAgent.launchMediaApplication(UserAgent.java:430)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.sipdroid.sipua.UserAgent.onCallAccepted(UserAgent.java:626)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.call.Call.onDlgInviteSuccessResponse(Call.java:312)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.dialog.InviteDialog.onTransSuccessResponse(InviteDialog.java:792)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.dialog.ExtendedInviteDialog.onTransSuccessResponse(ExtendedInviteDialog.java:322)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.transaction.InviteTransactionClient.onReceivedMessage(InviteTransactionClient.java:145)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.provider.SipProvider.processReceivedMessage(SipProvider.java:1076)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.provider.SipProvider.onReceivedMessage(SipProvider.java:1206)
12-19 10:43:03.285 26271-26297/com.hik.visapp W/System.err: at org.zoolu.sip.provider.UdpTransport.onReceivedPacket(UdpTransport.java:122)
12-19 10:43:03.286 26271-26297/com.hik.visapp W/System.err: at org.zoolu.net.UdpProvider.run(UdpProvider.java:189)
12-19 10:43:03.286 26271-26297/com.hik.visapp W/System.err: Error handling a new incoming message

传输层通知SipProvider偏向底层, 现在先跳过. SipProvider是怎样通知到Transaction的呢?

Version:0.9 StartHTML:-1 EndHTML:-1 StartFragment:0000000111 EndFragment:0000007686

/**
* SipProvider implements the SIP transport layer, that is the layer responsable
* for sending and receiving SIP messages. Messages are received by the callback
* function defined in the interface SipProviderListener.
* <p>
* SipProvider implements also multiplexing/demultiplexing service through the
* use of SIP interface identifiers and <i>onReceivedMessage()<i/> callback
* function of specific SipProviderListener.
* <p>
* A SipProviderListener can be added to a SipProvider through the
* addSipProviderListener(id,listener) method, where: <b> - <i>id<i/> is the
* SIP interface identifier the listener has to be bound to, <b> - <i>listener<i/>
* is the SipProviderListener that received messages are passed to. <p/> The SIP
* interface identifier specifies the type of messages the listener is going to
* receive for. Together with the specific SipProvider, it represents the
* complete SIP Service Access Point (SAP) address/identifier used for
* demultiplexing SIP messages at receiving side. <p/> The identifier can be of
* one of the three following types: transaction_id, dialog_id, or method_id.
* These types of identifiers characterize respectively: <br> - messages within
* a specific transaction, <br> - messages within a specific dialog, <br> -
* messages related to a specific SIP method. It is also possible to use the the
* identifier ANY to specify <br> - all messages that are out of any
* transactions, dialogs, or already specified method types.
* <p>
* When receiving a message, the SipProvider first tries to look for a matching
* transaction, then looks for a matching dialog, then for a matching method
* type, and finally for a default listener (i.e. that with identifier ANY). For
* the matched SipProviderListener, the method <i>onReceivedMessage()</i> is
* fired.
*/

译: SipProvider继承了SIP传输层的接口, 用来响应SIP消息的收/发. 消息的接收由SipProviderListener回调接口实现. 通过SIP接口标识和onReceivedMessage()回调函数(调用)指定的SipProvider监听器, SipProvider还继承了multiplexing/demultiplexing的复用服务功能. 一个SipProvider监听器可以通过addSipProviderListener(id,listener)方法添加到SipProvider的监听表, id是SIP接口标识, listener是收到的msg对应的监听者. SIP接口会根据msg类型区分不同的监听者. msg+指定监听者+指定SipProvider, 代表了一个接收处理方完整的SIP服务访问点(SIP SAP)地址/id. Identification有以下三类:(1)transaction_id; (2)dialog_id; (3)method_id. 这三种标识分别代表了: 包含指定transaction_id的msg; 包含指定dialog_id的msg; 包含指定method_id的msg. 当然也可以通过标识"ANY"来区分: 表示所有msg都不属于以上三类. 每当接收到一个msg时, SipProvider寻找id匹配的顺序是: transaction->dialog->method->default listener(ANY). 如果匹配, 对应的SipProviderListener的onReceivedMessage()方法将被调用.

Sipdroid实现SIP(三): 消息接收处理的更多相关文章

  1. 微信公众平台开发教程Java版(三) 消息接收和发送

    https://www.iteye.com/blog/tuposky-2017429 前面两章已经介绍了如何接入微信公众平台,这一章说说消息的接收和发送 可以先了解公众平台的消息api接口(接收消息, ...

  2. Sipdroid实现SIP(六): SIP中的请求超时和重传

    目录 一. Sipdroid的请求超时和重传 二. SIP中超时和重传的定义 三. RFC中超时和重传的定义 一. Sipdroid的请求超时和重传 Sipdroid实现SIP协议栈系列, 之前的文章 ...

  3. Sipdroid实现SIP(一): 注册

    目录 注册: 预注册获取长号和用户注册 预注册返回长号 周期性用户注册 Receiver类概述 SipdroidEngine类概述 Sipdroid类中的用户注册: 注册代理和注册事务 注册代理类Re ...

  4. 微信开发——微信公众平台实现消息接收以及消息的处理(Java版)

    本文主要讲述了如何在微信公众平台实现消息接收以及消息的处理,使用java语言开发,现在把实现思路和代码整理出来分先给兄弟们,希望给他们带来帮助. 温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微 ...

  5. 微信开发之消息接收与回复--weixin-java-tools

    一.前言 在上一篇文章<微信开发之如何使用开发工具--weixin-java-tools>中我给各位介绍了weixin-java-tools,并且介绍了如何使用weixin-java-to ...

  6. RabbitMQ:消息发送确认 与 消息接收确认(ACK)

    默认情况下如果一个 Message 被消费者所正确接收则会被从 Queue 中移除 如果一个 Queue 没被任何消费者订阅,那么这个 Queue 中的消息会被 Cache(缓存),当有消费者订阅时则 ...

  7. Bitter.NotifyOpenPaltform : HTTP 异步消息接收调度中心&mdash;开源贡献 之 一:简介

    现在互联网的系统越来越趋向于复杂,从单体系统到现在的微服务体系演变.公司与公司的分工也越来越明确. 大数据公司提供了大数据服务 人脸识别公司提供了人脸识别服务 OCR 公司提供了专业的OCR 服务 车 ...

  8. Bitter.NotifyOpenPaltform : HTTP 异步消息接收调度中心--开源贡献 之 一:简介

    现在互联网的系统越来越趋向于复杂,从单体系统到现在的微服务体系演变.公司与公司的分工也越来越明确. 大数据公司提供了大数据服务 人脸识别公司提供了人脸识别服务 OCR 公司提供了专业的OCR 服务 车 ...

  9. XAMARIN.ANDROID SIGNALR 实时消息接收发送示例

    SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...

随机推荐

  1. Topics

    Topics Introduction (starting with old devices) How to handle a new Firmware How to set up your Mac ...

  2. CSS盒子的浮动

    web前端学习笔记(CSS盒子的浮动) 在标准流中,一个块级元素在水平方向会自动伸展,直到包含它的元素的边界:而在竖直方向和兄弟元素依次排列,不能并排.使用“浮动”方式后,块级元素的表现就会有所不同. ...

  3. JavaScript原型与继承

    JavaScript原型与继承 原型 在JavaScript中,每个函数都有一个prototype属性,这个属性是一个指针,指向该函数的原型对象.这个原型对象为所有该实例所共享.在默认情况下,原型对象 ...

  4. 简单的mvc之二:蜿蜒的管线

    关于系列的第二篇,在管线与路由之间犹豫了很久,最终选择了管线—为免于盲人摸象的困惑. 管线的位置在哪里呢?webform,mvc以及web api都架构于asp.net平台上,管线则是asp.net的 ...

  5. [iOS]封装单例类

    [iOS]封装单例类 今天在学习iOS的SQLite开发,发现在需要使用SQLite的每个视图中,都需要对数据库进行打开或关闭,觉得挺麻烦的:于是在想能否写个单例类对这些操作进行封(因以前一直在使用D ...

  6. iOS多线程的初步研究1

    iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...

  7. sql server DateTime相关内置函数总结

    本文部分内容参考msdn帮助文档和博客园!汇总备忘 1.获取当前日期      getdate()函数以datetime数据类型的格式返回当前SQLServer服务器所在计算机的日期和时间.其语法格式 ...

  8. Fast Token Replacement in C#

    http://www.codeproject.com/Articles/298519/Fast-Token-Replacement-in-Csharp Fast Token Replacement i ...

  9. a5站长论坛和s8站长论坛-网上兼职做任务赚钱的两大网站

     1.什么是做任务赚钱? 简而言之,就是你做别人不在行而你在行的技术 ,如 图片美化 网站建设 网站修改 网站推广等网络业务. 2.任务赚钱有什么特点? 完全免费,你付出的是技术和时间,完全免费,不过 ...

  10. Linux登录ssh携带密码

    最近在使用ssh,但是每次都需要输入密码,想简单一步搞定,Google了一下,发现了一个比较笨的但实用的方法 1.安装 sshpass sudo apt-get install sshpass 2.携 ...