jDiameter是Diameter协议的开源实现(比较不幸的是AGPL 3.0协议),项目地址https://github.com/RestComm/jdiameter

项目框架

jDiameter由它自己和ha(主要是多个java实例如何进行数据共享)组成,各自又分为api和impl两部分,api定义了接口,而impl则是实现。ha部分不在本文讨论范围。

图1

图1是一个jDiameter框架主要部分的简单示意图,一个Diameter应用由两部分组成,即base部分和application部分(如Sh应用)。在jDiameter中,由Stack负责diameter base协议部分的初始化和启动工作,Application则通过注册监听函数的方式被调用。

在Diameter协议中,各个应用即Peer是对等的,没有主从的区分,也不区分客户端和服务器。jDiameter实现中Peer表示一个对等的远端Diameter应用,PeerFSM负责Peer的状态机,TransportLayer则是负责维持一个本Peer到对等Peer的长连接。注意jDiameter中有server和client代码包,而且server代码是继承自client的,这只是实现上逻辑的划分,不表示可以只用client部分启动jDiameter。Router则表示如何在多个Peer中选择路由。AppSession包含BaseSession,表示一个会话,数据存于SessionData Store中(本地或者ha),注意有的应用如Gx/Gy有状态,而有的如Sh是无状态的。

启动

下面我们来看一个例子如何使用jDiameter实现一个Sh应用:

 public class testServer extends ShSessionFactoryImpl implements NetworkReqListener {

     private static final Logger logger = Logger.getLogger(testServer.class);
public static StackImpl stack;
public static ISessionFactory sessionFactory; public static void main(String args[]) throws Exception {
PropertyConfigurator.configure("log4j.properties");
testServer t = testServer.init("config.xml");
t.start();
while (true) {
Thread.sleep(10000);
}
} public testServer(SessionFactory sessionFactory) {
super(sessionFactory);
} public static testServer init(String fileName) {
try {
XMLConfiguration config = new XMLConfiguration(fileName);
stack = new StackImpl();
sessionFactory = (ISessionFactory) stack.init(config);
testServer t = new testServer(sessionFactory);
Network network = stack.unwrap(Network.class);
network.addNetworkReqListener(t, ApplicationId.createByAuthAppId(10415, 16777217));
sessionFactory.registerAppFacory(ServerShSession.class, t);
sessionFactory.registerAppFacory(ClientShSession.class, t);
return t;
} catch (Exception e) {
logger.error("Failed:", e);
System.exit(-1);
}
return null;
} public void start() throws IllegalDiameterStateException, InternalException {
stack.start();
}

例1

例1展示了如何初始化并启动一个Sh应用服务器(模拟HSS)。主要步骤为:

  1. 通过xml配置初始化Stack,得到session factory.
  2. 初始化app session factory,这里是ShSessionFactoryImpl,testServer继承自它。
  3. 注册app session listener,这里由于继承关系没有体现,可以使用如下代码:
((ShSessionFactoryImpl) appSessionFactory).setClientShSessionContext(this);
((ShSessionFactoryImpl) appSessionFactory).setClientShSessionListener(this);
((ShSessionFactoryImpl) appSessionFactory).setStateChangeListener(this);
  1. 注册network request listener,监听app request。
  2. 注册app session factory到session factory。
  3. 启动Stack。

配置文件

下面是上例所需的配置文件:

<?xml version="1.0"?>
<Configuration xmlns="http://www.jdiameter.org/jdiameter-server">
<LocalPeer>
<URI value="aaa://hss1.server.test.com:3868" />
<IPAddresses>
<IPAddress value="1.1.1.1" />
</IPAddresses>
<Realm value="server.test.com" />
<VendorID value="0" />
<ProductName value="hssServer" />
<FirmwareRevision value="1" />
</LocalPeer>
<Parameters>
<AcceptUndefinedPeer value="true" />
<DuplicateProtection value="true" />
<DuplicateTimer value="240000" />
<UseUriAsFqdn value="false" />
<QueueSize value="10000" />
<MessageTimeOut value="60000" />
<StopTimeOut value="10000" />
<CeaTimeOut value="10000" />
<IacTimeOut value="30000" />
<DwaTimeOut value="10000" />
<DpaTimeOut value="5000" />
<RecTimeOut value="10000" />
<Concurrent>
<Entity name="ThreadGroup" size="64" />
<Entity name="ProcessingMessageTimer" size="16" />
<Entity name="DuplicationMessageTimer" size="16" />
<Entity name="RedirectMessageTimer" size="16" />
<Entity name="PeerOverloadTimer" size="16" />
<Entity name="ConnectionTimer" size="16" />
<Entity name="StatisticTimer" size="16" />
<Entity name="ApplicationSession" size="32"/>
</Concurrent>
</Parameters>
<Network>
<Peers>
<Peer name="aaa://sh.client.test.com:3868" ip="2.2.2.2" attempt_connect="false" rating="1" />
</Peers>
<Realms>
<Realm name="client.test.com" peers="sh.client.test.com" local_action="LOCAL" dynamic="false" exp_time="10000">
<ApplicationID>
<VendorId value="10415" />
<AuthApplId value="16777217" />
<AcctApplId value="0" />
</ApplicationID>
</Realm>
</Realms>
</Network>
<Extensions />
</Configuration>

config.xml

LocalPeer 配置自己的相关信息。

Parameters 配置的是jDiameter相关参数。

Network 配置的是其他Peer的信息。

详细结构可以参考jDiameter源码中的src/main/resources/jdiameter-server.xsd。

实现App回调

接上例我们来实现Sh应用服务器,主要有如下方法需要实现:

图2

下例是其中的一部分处理UserDataRequest:

     @Override
public Answer processRequest(Request request) {
int code = request.getCommandCode();
if (code != ProfileUpdateRequest.code && code != UserDataRequest.code && code != SubscribeNotificationsRequest.code) {
logger.error("Received Request with code not used by Sh!. Code[" + request.getCommandCode() + "]");
return null;
}
try {
AppSession serverShSession = ((ISessionFactory) sessionFactory).getNewAppSession(request.getSessionId(), appId, ServerShSession.class, (Object) null);
((NetworkReqListener) serverShSession).processRequest(request);
} catch (Exception e) {
logger.error("Fail to creat serverShSession", e);
}
return null;
} @Override
public void doUserDataRequestEvent(ServerShSession session, UserDataRequest request)
throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
UserDataAnswer answer = new UserDataAnswerImpl((Request) request.getMessage(), 2001);
AvpSet set = answer.getMessage().getAvps();
set.removeAvp(Avp.DESTINATION_HOST);
set.removeAvp(Avp.DESTINATION_REALM);
set.addAvp(Avp.USER_DATA_SH, "testdata", appId.getVendorId(), true, false, true);
session.sendUserDataAnswer(answer);
session.release();
}

例2

其他回调方法类似。

jDiameter负责连接对等的Peer,接受发送消息并解析,然后通过ApplicationId往上抛到回调函数处理Application业务逻辑。

待续…

jDiameter介绍以及使用的更多相关文章

  1. CSS3 background-image背景图片相关介绍

    这里将会介绍如何通过background-image设置背景图片,以及背景图片的平铺.拉伸.偏移.设置大小等操作. 1. 背景图片样式分类 CSS中设置元素背景图片及其背景图片样式的属性主要以下几个: ...

  2. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  3. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  4. Linux下服务器端开发流程及相关工具介绍(C++)

    去年刚毕业来公司后,做为新人,发现很多东西都没有文档,各种工具和地址都是口口相传的,而且很多时候都是不知道有哪些工具可以使用,所以当时就想把自己接触到的这些东西记录下来,为后来者提供参考,相当于一个路 ...

  5. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  6. HTML DOM 介绍

    本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...

  7. HTML 事件(一) 事件的介绍

    本篇主要介绍HTML中的事件知识:事件相关术语.DOM事件规范.事件对象. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三 ...

  8. HTML5 介绍

    本篇主要介绍HTML5规范的内容和页面上的架构变动. 目录 1. HTML5介绍 1.1 介绍 1.2 内容 1.3 浏览器支持情况 2. 创建HTML5页面 2.1 <!DOCTYPE> ...

  9. ExtJS 4.2 介绍

    本篇介绍ExtJS相关知识,是以ExtJS4.2.1版本为基础进行说明,包括:ExtJS的特点.MVC模式.4.2.1GPL版本资源的下载和说明以及4种主题的演示. 目录 1. 介绍 1.1 说明 1 ...

随机推荐

  1. “享受”英语的快乐—我是如何学英语的

    一:扬长避短重新认识英语课本 目前市场上的课本都有弊端,<新概念><走遍美国><疯狂英语>等等,不怪你学不下去,不是你的问题,课本本身就有漏洞的,但我怎么学的呢,我 ...

  2. 如何准备PMP考试?

    东西在精,而不在多.话不多说,干货如下: 1.参加培训,不要持续时间太长,通常情况下3个月时间足够了:许多和我一起参加培训的学员,有时候准备6个月时间,反而没有3个月冲刺的时间考试结果好. 2.培训老 ...

  3. SQL SERVER UNION和UNION ALL

    union与union allunion 缺省在合并结果集后消除重复项,union all 指定在合并结果集后保留重复项, 打个比喻吧 比如A表的数据是 A{ 1,4,5,9}       B{2,3 ...

  4. HTML5[6]:多行文本显示省略号

    CSS3新增text-overflow: ellipse; 只支持单行文本 如果是多行文本, 在无法完全显示的情况下,可以按下面这样写: overflow:hidden; display: -webk ...

  5. 爬虫技术 -- 基础学习(一)HTML规范化(附特殊字符编码表)

    最近在做网页信息提取这方面的,由于没接触过这系列的知识点,所以逛博客,看文档~~看着finallyly大神的博文和文档,边看边学习边总结~~ 对网站页面进行信息提取,需要进行页面解析,解析的方法有以下 ...

  6. 爬虫技术 -- 基础学习(五)解决页面编码识别(附c#代码)

    实现从Web网页提取文本之前,首先要识别网页的编码,有时候还需要进一步识别网页所使用的语言.因为同一种编码可能对应多种语言,例如UTF-8编码可能对应英文或中文等语言. 识别编码整体流程如下: (1) ...

  7. web.config中httpRunTime的属性

    配置httpRuntime也可以让FileUpload上传更大的文件,不过设置太大了会因用户将大量文件传递到该服务器而导致的拒绝服务攻击(属性有说明) <httpRuntime> < ...

  8. [python]新手写爬虫v2.5(使用代理的异步爬虫)

    开始 开篇:爬代理ip v2.0(未完待续),实现了获取代理ips,并把这些代理持久化(存在本地).同时使用的是tornado的HTTPClient的库爬取内容. 中篇:开篇主要是获取代理ip:中篇打 ...

  9. CentOS6.4安装包初识

    LiveCD 一般用来修复系统使用,有容量很小,不用安装,可以自启动等特性.bin DVD也具有同 样的功能,但是体积较大,所以会有live DVD. LiveDVD 与LiveCD 相同是不需要安装 ...

  10. log4net日志记录

    这里是接着上一篇来优化的,上篇:ASP.NET MVC中错误日志信息记录 log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件,数据库,EventLog等),日志就是程序的黑 ...