`
C_J
  • 浏览: 127966 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

飞信Client和MapleFetion项目的登录模块浅析

阅读更多

题记:

      反正闲着还是闲着。以下分析基于MapleFetion2.5版本。

     

    以前在DD的时候,XX做了一个告警短信系统,后来问了下孙总,他说只是XX提供了接口,应用这边给个文件就好了。所以此路XXX了。

 

    最早研究起Fetion的大哥应该是邓东东,记得之前面试我还提到过他的名字,他的LibFetion也是自己做黑盒分析做出来的,算是第三方最好的了,也做了很久,用c写的,见http://www.libfetion.org 原是本着美好的愿望,希望大家在此基础上开发更好的应用,无奈由于非技术原因,不提供对外的so库,特别是windows版本的,你懂的....

    虽然不对外提供so库,但却出了各个平台的飞信app应用了。国家要有个无私奉献奖就好了。

   

    听说飞信是MSN那帮人做的,而且做法有很多相似的地方。在2007年的时候nathan大哥也对其研究了一番,见他博客http://hi.baidu.com/nathan2007/home,他的博客要是被那帮开发人员看见了,估计会喷血。我想nathan的博客对后来研究飞信的人提供了很大的帮助。其中一个就是MapleFetion项目了,作者solosky也是做了一番苦心的研究,最终开发了一个功能较全的三方lib,并且开源出来了,我觉得这对飞信本身的发展是利大于弊的。

 

    根据nathan大哥的黑盒分析,了解到fetion用到非标准的SIP协议+HTTP协议,在SIP上做了一点改动,感觉是被阉了,并改名叫SIPC。

    飞信的登录模块有2次验证:

    1、SSI验证

    通过HTTPS的GET方式通讯,URL为:https://uid.fetion.com.cn/ssiportal/SSIAppSignInV2.aspx?mobileno=159********&domains=fetion.com.cn%3bm161.com.cn%3bwww.ikuwa.cn&digest=89405402A0FC1A2FC73681229FB134E9638C4D5986C65BC9

 

digest后面那段是密码。

 

得到SIP:123456@fetion.com.cn;p=6721,结果码,和一个Credential

类似如下:

 

  <?xml version="1.0" encoding="utf-8" ?> 
- <results status-code="200">
- <user uri="sip:123456@fetion.com.cn;p=6721" mobile-no="159********" user-status="101" user-id="1233333">
- <credentials>
  <credential domain="fetion.com.cn" c="CBIOAADZDl2PfBl6ezl2Ljt9sWajwx2thKDwACt0dGTJ8gfb4C71CTLB7d8pxAD0BduMh7rO77pdWHIhHP2m0c7TRxQecfzOUCEfTyL09KaRQblUICPlBl/Whtp1M6WipxsyfX4AAA==" /> 
  <credential domain="m161.com.cn" c="CBAOAAAOPH9ouHxCxcsfS+XMPuAA8zN4nCaWV4t7mnHM6pkp6VHs1enfBCx/VT5lZ5lXU0WITAfctJ1f8wA4uUfyc1REihCQV/goRNumQC3VQinD1A==" /> 
  <credential domain="www.ikuwa.cn" c="ChAOAACTP8rQqlM7Sr3DbtWpRZv8HNrJpadWYWG0XWt3oNPWdSjx135Fk39Ghje1w4rdwZJ7eYtWX7/vv9lqD0uQzoio8CVuapOKZ1QcGa4fNJKaXQ==" /> 
  </credentials>
  </user>
  </results>

 

登录代码为:LoginState state = client.syncLogin();

登录主要类为:LoginWork.java

 

 LoginWork的工作包括了2次身份验证。完成了上一步,就开始SIPC的交互过程了,另外你可以不走SSI验证过程,但是你就必须得知道你的Fetion号,而非手机号。

 

SSI身份验证是类SSISignV2.java实现的,主要工作就是生成URL,发送HTTPS请求,接收HTTPS返回的结果,并解析,代码很简单,就不贴了。

SIPC验证是ServerDialog.java实现的,他主要工作是与飞信服务器进行通讯,其中包括消息的构造和发送。

 

在FetionClient初始化时会建立几个工厂:

 

public FetionClient(String account,
      String password,
      NotifyEventListener notifyEventListener)
 {
  this(new User(account, password, "fetion.com.cn"),
    notifyEventListener,
    new AutoTransferFactory(),
    new SimpleFetionStore(),
    new ThreadTimer(),
    new SingleExecutor());
 }

 

关于登录的运行有点怪怪的,作者用一个 new SingleExecutor()(实际上是一个1.5的单线程池:Executors.newSingleThreadExecutor();)来执行LoginWork。

 

 

2、开始SIPC验证

     前面分析到,与服务器的SIPC通讯主要是ServerDialog实现的,而他由DialogFactory工厂模式创建。

     和其他协议消息一样,消息分为头+消息体,由MessageFactory消息工厂创建,然后通过TCP,HTTP,MINA等底层通讯平台发送,消息被封装为SipcRequest.java,SipcResponse.java和SipcReceipt.java里。

 

    MessageFactory.java的主要作用就是构造一个个消息,消息构造就不贴代码了,很多硬编码了。 

 

    构造好消息后,传给上层ServerDialog.java,并由ServerDialog通过发送模块发送出去,并注册监听器。这个看得有点头昏,需要关注下,代码如下:

 

  /**
	 * 注册服务器
	 * @param presence		登录状态
	 * @param listener
	 */
	public void register(int presence, ActionEventListener listener)
	{
		SipcRequest request = this.getMessageFactory().createServerRegisterRequest(presence, 
					this.context.getTransferFactory().isMutiConnectionSupported());
		request.setResponseHandler(new ServerRegisterResponseHandler(context, this, listener));
		this.process(request);// 发送消息
		
	}

   

  /**
     * 发送数据包
     */
    @Override
    public void process(SipcOutMessage out)
    {
    	try {
	        this.processorChain.getFirst().processOutcoming(out);
        } catch (FetionException e) {
        	this.handleException(e);
        	//如果是传输异常,就将其抛出,让调用者处理传输错误
        	if(out instanceof SipcRequest) {
        		SipcRequest request = (SipcRequest) out;
        		if(request.getResponseHandler()!=null)
        			request.getResponseHandler().ioerror(request);
        	}
        }
    }

 

     看到发送消息通过process(request);从这个process看不出什么名堂。但是注意到在ServerDialog初始化的时候,初始化了这些process,如下:

 

 

    public void buildProcessorChain() throws FetionException
    {
		this.processorChain = new ProcessorChain();
		this.processorChain.addLast(new ServerMessageDispatcher(context, this, this));						//消息分发服务
		if(FetionConfig.getBoolean("log.sipc.enable"))
			this.processorChain.addLast(new SipcLogger("ServerDialog-"+this.context.getFetionUser().getFetionId()));									//日志记录
		this.processorChain.addLast(new TransferService(this.context));															//传输服务
		this.processorChain.addLast(new SipcParser());															//信令解析器
		this.processorChain.addLast(this.context.getTransferFactory().createDefaultTransfer());				//信令传输对象
		
		this.processorChain.startProcessorChain();
		
    }

其中 this.processorChain.addLast(new TransferService(this.context));建立一个传输processor放入processorChain这个以processor为节点的双链表。

 

我不太明白作者这样做的理由,看上去比较乱,processorChain里面什么都有,只能继续分析看看。

 

重新看了下各类Processor的处理逻辑后发现,原来作者的这个processorChain相当于一个过滤器,一个最原始的Request需要经过processorChain中每一个processor的处理,比如第一个是ServerMessageDispatcher模块,处理完后把Request对象传递给SipcLogger模块,从前往后,这样一层一层处理,最后由发送模块,也就是TCPTransfer的sendBytes进行发送。如下:

 

处理流程为:ServerMessageDispatcher-->SipcLogger-->TransferService-->SipcParser-->createDefaultTransfer-->网络-->飞信服务器

 

 protected void sendBytes(byte[] buff, int offset, int len)
            throws TransferException
    {
    	try {
	        this.writer.write(buff, offset, len);
	        this.writer.flush();
        } catch (IOException e) {
	       throw new TransferException(e);
        }
    	
    }

 

 这种把处理模块做成双链表的设计模式感觉还是有利有弊:),还是等待大大点评下吧。 

 

分享到:
评论
3 楼 zhhaogen 2010-11-17  
很少人研究第三方qq么?
2 楼 agapple 2010-11-17  
对协议分析是个体力活

http://agapple.iteye.com/blog/813225,个人的一个fetion lib使用记录,直接用的是一个别人的lib库
1 楼 C_J 2010-11-16  
<div class="quote_title">solosky 写道</div>
<div class="quote_div">HI CJ.Yang:<br>   ProcessorChain是从设计模式中的职责链设计模式变化而来的,通过在这条双向的链表上传递一个对象,每个处理器可以进行处理或者替换后交给下一个处理器,也可以直接切断处理链。这样做是为了形成类似于堆栈似的协议处理,而且有明显的分层,每一层都完成独立的处理,下面是maplefetion的处理链的结构,或者叫处理栈更贴切些:<br><br>Dialog  //最顶层,发起某一个操作,比如添加好友,会构建一个SipcRequest传递给下一层,并且捕获所有的异常和处理<br>   ↓↑<br>MessageDispatcher  //路由从底层传递上来的SipcNotify和SipcResponse,调用NotifyHandler和ResponseHandler<br>   ↓↑<br>SipcLogger     //记录所有和服务器交互的Sipc信令,便于调试<br>   ↓↑<br>TransferService // 管理Sipc信令的传输,处理超时和重传,以及SipcResponse和SipcRequest的配对<br>   ↓↑<br>SipcParser     //解析底层传递过来的字节数组为单独的Sipc信令,并交个上层处理,和把上层传递过来的Sipc信令转为字节数组,交给下层发送;<br>   ↓↑<br>Transfer    //发送和接受网络传递的字节数组<br><br>通过这种处理链的方式,可以很容易构建起分层的处理结构,并且可以很方便的在这个处理链上添加新处理器来添加新的功能,很容易维护。<br>缺点嘛,暂时没想到,呵呵。 <br><br>如果你看过Tomcat的源码,其实里面的Valve也是一个处理链的结构,对于每一个请求都会在有Valve构成的链表中传递和处理,还有Filter也是。<br>希望对你有所帮助。</div>
<p> </p>
<p> </p>

相关推荐

    MyKTV项目 client前台项目

    总结来说,MyKTV项目client前台的开发涵盖了前端开发的多个方面,包括但不限于框架选择、页面布局、数据交互、错误处理、安全性和性能优化。虽然存在未完善之处,但其完整性和实践性仍然为学习和理解前端开发提供了...

    Springboot整合dubbo构建maven多模块项目- test

    1. 创建Maven多模块项目结构,包括父模块和"Server"、"Client"子模块。 2. 在父模块的pom.xml中定义共有的依赖管理和插件配置。 3. 在"Server"模块中引入Spring Boot和Dubbo的依赖,编写服务接口和服务实现。 4. ...

    飞信多开操作方式 Client.config

    总的来说,飞信多开通过修改`Client.config`文件中的`SingleInstance`设置,实现了对飞信默认单实例限制的解除,让用户可以同时运行多个飞信客户端,但这也需要用户了解潜在的风险,并自行承担可能的后果。

    使用Simulink配置AUTOSAR Client-Server通信

    在Simulink中,客户端和服务器的配置通常涉及到使用Simulink提供的特定模块(如Simulink Function模块)来模拟Client-Server通信,并生成相应的代码以部署到AUTOSAR平台上。 从给定的文件内容来看,配置AUTOSAR ...

    clientDEMO clientdemo调试软件

    2. 项目调试:在项目实施阶段,开发人员可以利用clientDEMO进行网络环境的测试和调试,确保项目部署的顺利进行。 3. 教学培训:在教学或培训中,clientDEMO可以作为实践工具,让学生更好地理解和掌握网络监控和调试...

    spring RichClient spring RichClient 示例源码

    Spring RichClient是一个基于Spring框架的桌面应用程序开发平台,它提供了丰富的用户界面组件和灵活的架构,使得开发人员能够更容易地创建功能强大的企业级桌面应用。这个项目已经不再维护,但其设计理念和实现方式...

    instantclient_10_2和instantclient_11_2

    python连接oracle,使用cx_Oracle模块,模块版本和客户端版本不对应 python版本3.8 Oracle11 cx_Oracle 8.3 问题一.cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: 解决一:...

    飞信SDK开发控件接口

    这个SDK适用于多种编程语言,包括C#和Delphi,使得开发者能够利用飞信的功能来创建自定义的通信解决方案。在本文中,我们将深入探讨飞信SDK的核心概念、接口、使用场景以及如何在C#和Delphi环境下进行开发。 一、...

    maven创建多模块web项目.docx

    总结来说,创建Maven多模块Web项目的关键在于正确配置父子模块关系和模块间的依赖。通过这种方式,我们可以有效地组织和管理大型项目,确保代码的清晰性和可维护性。同时,Maven的自动构建功能能够简化构建过程,...

    SVNClient华为工具

    9. **性能优化**:针对大规模项目和高并发场景,华为SVNClient可能进行了性能优化,以提升传输速度和系统响应时间。 10. **培训和支持**:华为可能提供相关的培训材料和技术支持,帮助员工快速上手并熟练使用SVN...

    Kingdee.BOS.WebApi.Client.dll反编译项目,用于解决Newtonsoft.Json冲突

    这个项目的标题和描述提及了"Kingdee.BOS.WebApi.Client.dll",这是一个与金蝶(Kingdee)业务操作平台(BOS)相关的Web API客户端库。问题在于它与流行的JSON序列化库"Newtonsoft.Json"之间存在冲突。 首先,让...

    前端开源库-spm-client

    4. **依赖管理**:spm-client维护项目中的依赖树,确保各个模块之间的一致性和兼容性,避免版本冲突。 5. **构建优化**:在项目构建过程中,spm-client可以进行代码压缩、合并,以及生成源码映射,便于调试和优化。...

    飞信2008 c#源码

    移动飞信完美版C#源代码\FetionFx\Imps\Client\Logger\ImpsLogger.cs 移动飞信完美版C#源代码\FetionFx\Imps\Client\Logger\LogHeader.cs 移动飞信完美版C#源代码\FetionFx\Imps\Client\Pc\AboutMe.cs 移动飞信完美...

    springboot多模块框架demo

    【SpringBoot多模块框架demo】是一个综合性的项目实例,它结合了SpringBoot、MyBatis...通过学习和理解这个项目,开发者可以深入了解SpringBoot、MyBatis和Webservice的集成应用,以及如何组织一个多模块的Java项目。

    mac华为SVNClient

    总的来说,mac华为SVNClient是Mac用户在进行协同开发时的重要工具,它通过强大的SVN功能帮助团队成员有效管理和跟踪代码版本,提升开发效率,保证项目稳定性和质量。对于熟悉Windows版QuidwayClient的用户,转换到...

    OPC_CLIENT 模块

    一个OPC VB CLIENT的VB 模块类,可以学习

    SQL Server Native Client 10.0

    SQL Server Native Client 10.0 是微软为SQL Server 2008和2008 R2设计的一个数据库访问接口,它集成了ODBC(Open Database Connectivity)和OLE DB(Object Linking and Embedding, Database)接口。在SQL Server ...

    Kepware使用教程—OPC Quick Client具体使用

    OPC Quick Client是Kepware提供的一个轻量级工具,它简化了与OPC服务器的连接和数据交互,尤其适合初学者快速了解和使用OPC技术。 在使用OPC Quick Client时,首先需要理解OPC的基础概念。OPC分为OPC DA(Data ...

    邮件发送和飞信发送实例

    在IT行业中,邮件发送和飞信发送是两个重要的通信机制,尤其在自动化任务、通知服务以及用户互动中扮演着关键角色。本实例将探讨如何利用.NET框架中的SMTP/POP3功能来实现邮件发送,以及如何通过飞信的官方接口进行...

    FreeSwitch FsClient 客户端

    在部署FsClient时,确保用户的计算机上已经安装了.NET Framework的相应版本,并且FreeSwitch服务器已配置好所有必要的模块和服务。将FsClient应用程序部署到目标机器后,用户可以直接运行程序,按照界面提示进行设置...

Global site tag (gtag.js) - Google Analytics