为Diameter创建一个网络通道。 ? 配置Diameter节点和应用程序。
?
BEA文档页面的 参考资料 部分详述了这些步骤。
初始化
部署好的应用程序使用Diameter Rf或Ro功能之前,需要分别获取
RfApplication或RoApplication对象。这可以通过以下代码实现,假定使用的是SIP或HTTP servlet类:
ServletContext sc = getServletConfig().getServletContext();
Node node = (Node)sc.getAttribute(\
if(node == null) {
throw new ServletException(\ }
RfApplication rfApp = (RfApplication)
node.getApplication(Charging.RF_APPLICATION_ID);
if(rfApp == null) {
throw new ServletException(\diameter.xml\ }
RoApplication roApp = (RoApplication)
node.getApplication(Charging.RO_APPLICATION_ID);
if(roApp == null) {
throw new ServletException(\diameter.xml\ }
会话处理
Diameter有一个会话的概念。RFC3588中对会话的正式定义是“一系列致力于某个特定活动的 相关事件”。实际上,会话使用ACR(START)或CCR(INITIAL)表示开始,并以ACA(STOP)或CCA(TERMINATION)表示 结束。在一次性事件的例子中,会话只包含请求和应答。所有消息都属于一个与Session-Id AVP公共值相关的会话。
在 WebLogic SIP Server API中,Diameter会话是与
com.bea.wcp.diameter.Session对象映射在一起的。Session类处理Session- Id AVP。Rf和Ro接口有两个特殊的子类,即RfSession和RoSession。这两个类只处理特定于Diameter计费的请求和应答。可以使用 Rf/RoApplication创建会话对象:
RfApplication rfApp = ...
RfSession rfSes = rfApp.createSession(); RoApplication roApp = ...
RoSession roSes = roApp.createSession();
此外,DIAMETER会话是可序列化的,您可以将其作为属性存储于
SipApplicationSession中,反之亦然。WebLogic Sip Server会自动将会话链接到活动的呼叫状态。接收到消息之后,容器将自动检索呼叫状态,并找出Diameter会话。
创建Rf请求
创建Rf请求相当简单。让我们从一个基于会话的请求入手。如前所述,获得RfApplication和RfSession之后,我们使用 RfSession对象创建一个新Accounting-Request。由于这是第一个请求,requestType将以值的形式出现: ACR acr = session.createACR(RecordType.START); 创建Event请求的代码为:
ACR acr = session.createACR(RecordType.INTERIM); 创建一个新Accounting-Request时,将会自动填充以下AVP:
属性
值
Session-Id Origin-Host Origin-Realm
自动生成
根据diameter.xml中的节点设置 根据diameter.xml中的节点设置
RfApplication中cdf.host参数的值,设置在diameter.xml中
RfApplication中cdf.realm参数的值,设置在diameter.xml中
Acct-Application-Id 3,表示Diameter Base Accounting Destination-Host Destination-Realm
可以通过调用addAvp方法添加其他AVP:
Acr.addAvp(Attribute.EVENT_TIMESTAMP, new Integer(timestamp));
创建Ro请求
对Ro接口的请求(比如说Credit-Control-Requests)的创建方式非常类似于创建Accounting-Requests的方式。以下这个示例可以说明一切: CCR ccr = roSes.createCCR(RequestType.INITIAL);
注意,Credit Control的请求类型与账户的记录类型有所不同——比如,START和INITIAL。事件请求可直接通过RoApplication创建,而不需要明确地创建一个会话:
CCR eventCcr = roApp.createEventCCR();
在两种情况下,WebLogic SIP Server都会自动设置以下表格中的AVP。
属性 Session-Id Origin-Realm
值
根据diameter.xml中的节点设置 根据diameter.xml中的节点设置
RoApplication中ocs.host参数的值,设置在diameter.xml中
RoApplication中ocs.realm参数的值,设置在diameter.xml中
由createCCR()的参数指示;对于createEventCCR()其值为EVENT_REQUEST (4)
Auth-Application-Id 4,表示Diameter Credit-Control Destination-Host Destination-Realm CC-Request-Type
CC-Request-Number 会话每创建一个CCR该数字就自增1
可以使用与前面相同的方法添加其他AVP。
Diameter Base属性是Attribute类中的静态字段。此外,与计费相关的属性可以在Charging类和CreditControl类中找到。 WebLogic SIP Server并未限制用户使用这些预先定义的属性。可以使用Attribute.define()方法之一来创建新属性。Attribute类包含为所有 基本属性预先定义的常量。以下示例展示了如何添加一个AVP:
public static final Attribute SUBSCRIPTION_ID_TYPE =
Attribute.define(666, \
添加一个已经由用户或容器定义过的AVP时,WebLogic Sip Server会抛出一个异常。添加完所有必要的AVP后,我们最后还要发送CCR。可以使用以下两种方法完成这一操作: ccr.send(); // - or -
CCA answer = (CCA)ccr.sendAndWait();
第二种方法会发送CCR并阻塞执行,直到接收到应答或发生超时。
接收应答
WebLogic SIP Server Diameter API中有两种接收应答的方法。第一种是异步方式,以Request.sendAndWait()方法为基础。这个方法会发送请求并阻塞呼叫线程直到接收 到应答或请求超时。它会返回接收到的应答。发送请求的异步方式适用于阻塞线程不会造成问题的应用程序。
第二种方法是异步分离发送动作和 接收动作。请求是通过调用
Request.send()发送的。这个方法会立刻返回。接收到应答时,该方法会调用其rcvMessage()方法通知监听 程序。这个监听程序必须要实现SessionListener接口,而且必须要在接收到应答之前建立在会话中。以下示例演示了这种方法: //This is a listener class
class MyListener implements SessionListener {
public void rcvMessage(Message message) {
System.out.println(\
if(message.getCommand().equals(CreditControl.CCA)) {
System.out.println(\ } } }
//This code is inside some other (or the same) class, in a method
//responsible for sending the request
//Create session and listener
RoSession roSes = roApp.createSession();
MyListener myListener = new MyListener();
//Set the listener on the session
roSes.setListener(myListener);
//Now create and send a request
CCR ccr = roSes.createCCR(RequestType.INITIAL);
ccr.addAvp(...);
ccr.send();
//send() returns immediately. Answer will be received in
//myListener.rcvMessage()
带有监听程序的实现还可以允许我们接收当前会话内的服务器所发送的请求(比如说,当服务器决定马上关闭会话时所发送的Abort- Session-Request)。请求和应答都以同样的方式传递给监听程序的rcvMessage()方法。由应用程序负责为请求和应答提供不同的行 为。