分享

短信程序:基于CMPP3.0 协议SP端的实现C#

 昵称8888806 2012-03-02

短信程序:基于CMPP3.0 协议SP端的实现C# [复制链接]查看:554回复:0

1#
短信程序:基于 CMPP3.0 协议 SP 端的实现(C#)     最近一段是时间项目可能需要提供短信功能,客户作为一个 SP 端提供短信业务;网上搜索了一番,找到了比较不错的 CMPP30 类的代码,该代码基本实现了 CMPP3.0 协议中的短信收发、网络重连等功能。本人将其重新改造,提供了同步发送、异步发送的支持(原先版本的异步发送并非标准的 .NET 异步发送模式,这部分代码是一个异步操作实现的“范本”,可供大家参考),增加了对 PROVISION 接口的支持。     本人已将这些代码打包为一个 RAR 文件,稍后会上传到 Internet 供大家交流、学习;下面将对这版 CMPP30 类的 API 进行简要介绍:           1)用于收发短信 CMPP30 类的 API:

Code   1/**//// <summary>   2/// CMPP30 短信网关通讯组件(供 SP 使用)。   3/// </summary>   4public class CMPP30   5{   6   7    属性#region 属性   8    /**//// <summary>   9    /// SMS 事件。 10    /// </summary> 11 public event EventHandler<SMSEventArgs> SMS; 12    #endregion 13 14    构造函数#region 构造函数 15    /**//// <summary> 16    /// 初始化 <see cref="CMPP30"/> 类新实例。 17    /// </summary> 18 public CMPP30(string spid, string password, string address, int port); 19    #endregion 20 21    公有方法#region 公有方法 22    /**//// <summary> 23    /// 启动 CMPP30 服务。 24    /// </summary> 25 public void Start(); 26    /**//// <summary> 27    /// 发送短信。 28    /// </summary> 29    /// /// <param name="text"> 30    /// 信息内容。 31    /// </param> 32    /// <param name="encoding"> 33    /// 信息编码。 34    /// </param> 35    /// <param name="sourceID"> 36    /// SP的服务代码,将显示在最终用户手机上的短信主叫号码。 37    /// </param> 38    /// <param name="destinations"> 39    /// 接收短信的电话号码列表。 40    /// </param> 41    /// <param name="serviceID"> 42    /// 业务标识(如:woodpack)。 43    /// </param> 44    /// <param name="needReport"> 45    /// 是否要求返回状态报告。 46    /// </param> 47    /// <param name="feeType"> 48    /// 资费类别。 49    /// </param> 50    /// <param name="feeUserType"> 51    /// 计费用户。 52    /// </param> 53    /// <param name="feeUser"> 54    /// 被计费的号码(feeUserType 值为 FeeUser 时有效)。 55    /// </param> 56    /// <param name="realUser"> 57    /// 被计费号码的真实身份(“真实号码”或“伪码”)。 58    /// </param> 59    /// <param name="informationFee"> 60    /// 信息费(以“分”为单位,如:10 分代表 1角)。 61    /// </param> 62    /// <param name="linkID"> 63    /// 点播业务的 LinkID。 64    /// </param> 65 public CMPP_SUBMIT_RESP Send( 66        string text, 67        CEncoding encoding, 68        string sourceID, 69        string[] destinations, 70        string serviceID, 71        bool needReport, 72        FeeType feeType, 73        FeeUserType feeUserType, 74        string feeUser, 75        bool realUser, 76        int informationFee, 77        string linkID); 78    /**//// <summary> 79    /// 发送短信。 80    /// </summary> 81 public CMPP_SUBMIT_RESP Send(CMPP_SUBMIT submit); 82    /**//// <summary> 83    /// 开始异步发送短信。 84    /// </summary> 85    /// <param name="text"> 86    /// 信息内容。 87    /// </param> 88    /// <param name="encoding"> 89    /// 信息编码。 90    /// </param> 91    /// <param name="sourceID"> 92    /// SP的服务代码,将显示在最终用户手机上的短信主叫号码。 93    /// </param> 94    /// <param name="destinations"> 95    /// 接收短信的电话号码列表。 96    /// </param> 97    /// <param name="serviceID"> 98    /// 业务标识(如:woodpack)。 99    /// </param> 100    /// <param name="needReport"> 101    /// 是否要求返回状态报告。 102    /// </param> 103    /// <param name="feeType"> 104    /// 资费类别。 105    /// </param> 106    /// <param name="feeUserType"> 107    /// 计费用户。 108    /// </param> 109    /// <param name="feeUser"> 110    /// 被计费的号码(feeUserType 值为 FeeUser 时有效)。 111    /// </param> 112    /// <param name="realUser"> 113    /// 被计费号码的真实身份(“真实号码”或“伪码”)。 114    /// </param> 115    /// <param name="informationFee"> 116    /// 信息费(以“分”为单位,如:10 分代表 1角)。 117    /// </param> 118    /// <param name="linkID"> 119    /// 点播业务的 LinkID。 120    /// </param> 121    /// <param name="callback"> 122    /// 异步回调函数。 123    /// </param> 124    /// <param name="asyncState"> 125    /// 传递给异步回调函数的参数。 126    /// </param> 127 public IAsyncResult BeginSend( 128        string text, 129        CEncoding encoding, 130        string sourceID, 131        string[] destinations, 132        string serviceID, 133        bool needReport, 134        FeeType feeType, 135        FeeUserType feeUserType, 136        string feeUser, 137        bool realUser, 138        int informationFee, 139        string linkID, 140        AsyncCallback callback, 141        object asyncState); 142    /**//// <summary> 143    /// 开始异步发送短信。 144    /// </summary> 145 public IAsyncResult BeginSend( 146        CMPP_SUBMIT submit, 147        AsyncCallback cb, 148        object asyncState); 149    /**//// <summary> 150    /// 结束异步发送短信。 151    /// </summary> 152 public CMPP_SUBMIT_RESP EndSend(IAsyncResult ar); 153    /**//// <summary> 154    /// 停止 CMPP30 服务。 155    /// </summary> 156 public void Stop(); 157    #endregion 158 159}

CMPP30 类 API

                      这个类是核心类,我的代码注释很清楚,所以就不再赘述;需要注意一下的就是 Send、BeginSend、EndSend 是符合 .NET 框架标准的异步操

                  作模式;与网上的 CMPP30 类不用的是 Send 函数要求传入 CMPP_SUBMIT 数据包并返回一个 CMPP_SUBMIT_RESP 包,这有利于调用者得到

                  由 ISMG 服务器返回的 MsgID 字段,否则调用者只能通过 SMS 事件得到 CMPP_SUBMIT_RESP 包,但是仅仅有这个包是不能与其相对应的

                  CMPP_SUBMIT 进行匹配的。

                      另外说一下,所有与 ISMG 的交互都会导致 SMS 事件的引发,该事件参数中会提供一个 SMS_EVENT 枚举供事件处理程序使用,详细信息请参

                  考 SMS_EVENT 的代码。

                      最后对使用我代码的朋友说一下,Start 与 Stop 这两个函数只能调用一次。如果你的程序中调用 Stop 停止了 CMPP30 服务,则必须重新实例

                  化一个新的 CMPP30 对象来启动该服务。

          2)对 PROVISION 正向订购/取消接口的支持:                       根据 MISC1.6 的描述,对 PROVISION 接口的实现应该采用基于 SOAP 协议的 WEB 服务技术,我这里提供了一个 Provision 抽象类,该类继                承自 System.Web.Services.WebService。呵呵,看出来了吧,我的想法就是让 asmx 页的后台类继承 Provision 类。该类封装了 PROVISION 接                口中的 SyncOrderRelationReqSyncOrderRelationResp 包的实现,将这对“发送/响应”包的收发变为“一次对 WEB 服务函数的调用”,当接                收到 SyncOrderRelationReq 时就调用 Provision 类中的 SyncOrderRelationReq 函数(WebMethod),并将该函数返回值转变为一个                SyncOrderRelationResp 包返回给移动的服务器。API 代码如下:

Code   1/**//// <summary>   2/// 正向(反向)同步 PROVISION 接口服务。   3/// </summary>   4[WebService(Namespace = "http://www./dsmp/schemas/")]   5[SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]   6public abstract class Provision : System.Web.Services.WebService   7{   8   9    属性#region 属性 10    /**//// <summary> 11    /// SOAP 消息编号(DSMG 调用该 WEB 服务时需要设置该信息)。 12    /// </summary> 13    [EditorBrowsable(EditorBrowsableState.Never)] 14    public TransactionID TransactionID; 15    #endregion 16 17    保护方法#region 保护方法 18    /**//// <summary> 19    /// MISC 因为某种情况(如:用户通过手机短信的方式执行了某操作)更新了用户订购关系(包括:订购、取消、暂停、激活)的时候,通过此函数发起和 SP 的更新订购关系的交互。 20    /// </summary> 21    /// <param name="id"> 22    /// 消息编号。 23    /// </param> 24    /// <param name="sendAddr"> 25    /// 发送方的地址。 26    /// </param> 27    /// <param name="destAddr"> 28    /// 接收方的地址。 29    /// </param> 30    /// <param name="feeUserID"> 31    /// 计费用户标识。 32    /// </param> 33    /// <param name="destUserID"> 34    /// 使用用户标识(当使用用户和计费用户为同一用户的时候,FeeUser_ID 和 DestUser_ID 的值相同)。 35    /// </param> 36    /// <param name="linkID"> 37    /// 临时订购关系的事务 ID。 38    /// </param> 39    /// <param name="actionID"> 40    /// 服务状态管理动作代码(1:开通服务;2:停止服务;3:激活服务;4:暂停服务)。 41    /// </param> 42    /// <param name="actionReasonID"> 43    /// 产生服务状态管理动作原因的代码(1:用户发起行为;2:Admin&1860发起行为;3:Boss停机;4:Boss开机;5:Boss过户;6:Boss销户;7:Boss改号;8:扣费失败导致的服务取消;9:其他)。 44    /// </param> 45    /// <param name="spid"> 46    /// SP 的企业代码。 47    /// </param> 48    /// <param name="serviceID"> 49    /// 业务标识,是数字、字母和符号的组合(长度为 10,SP的业务类型,数字、字母和符号的组合,由SP自定,如图片传情可定为TPCQ,股票查询可定义为11),也叫做计费代码。 50    /// </param> 51    /// <param name="accessMode"> 52    /// 服务的访问方式(1:WEB;2:WAP;3:SMS)。 53    /// </param> 54    /// <param name="featureStr"> 55    /// 服务订购参数(base64加密),内容是长号码+空格+用户发送内容。 56    /// </param> 57    /// <param name="hResult"> 58    /// 返回值(0:成功;1:未知错误;2-99:保留;4000:无效的msgtype;4001:无效的action_id;4002:无效的action_reasonid;4003:无效的SP ID;4004:无效的serviceID;4005:无效的pseudocode;4006:无效的accessmode;4007:MISC 同步开通服务,但SP 端已存在订购关系,且状态为开通;4008:MISC 同步开通服务,且SP 端不存在订购关系,但开通服务失败;4009:MISC 同步开通服务,但SP 端已存在订购关系, 且状态为暂停;4010:MISC 同步停止服务, 且SP 端存在订购关系, 但取消服务失败;4011:MISC 同步停止服务, 但SP 端不存在订购关系;4012:MISC 同步暂停服务, 且SP 端存在订购关系, 但暂停服务失败;4013:MISC 同步暂停服务, 但SP 端不存在订购关系;4014:MISC 同步暂停服务, 但SP 端已存在订购关系, 且状态为暂停;4015:MISC 同步激活服务, 但SP 端已存在订购关系, 且状态为开通;4016:MISC 同步激活服务, 但SP 端不存在订购关系;4017:MISC 同步激活服务, 且SP 端存在订购关系, 但激活服务失败;9000:系统磁盘读写错误;9001:网络异常;9002:网络错误;9003:业务网关忙,业务网关缓存;9004:业务网关忙,并且业务网关缓冲区满,MISC 缓存,并暂时不要发送消息,等待一段时间重试;9005:MISC 忙,MISC 缓存;9006:MISC 忙,并且MISC 缓冲区满,业务网关缓存,并暂时不要发送消息,等待一段时间重试;9007:业务网关超过限制的流量;9008:MISC 异常,并不可用;9009:业务网关异常,并不可用;9010:该业务网关没有权限调用该接口消息;9011:MISC 没有权限发送该接口消息给业务网关;9012:版本不支持;9013:消息类型不对,系统不支持;9014:验证错误,无法解析SOAP 和XML 结构、缺少必须存在的字段,或者消息,格式不正确;9015:拒绝消息,服务器无法完成请求的服务)。 59    /// </param> 60 protected abstract void OnSyncOrderRelationReq( 61        string id, 62        AddressInfo sendAddr, 63        AddressInfo destAddr, 64        UserID feeUserID, 65        UserID destUserID, 66        string linkID, 67        int actionID, 68        int actionReasonID, 69        string spid, 70        string serviceID, 71        int accessMode, 72        byte[] featureStr, 73        out int hResult); 74    #endregion 75 76    公有方法#region 公有方法 77    /**//// <summary> 78    /// MISC 因为某种情况(如:用户通过手机短信的方式执行了某操作)更新了用户订购关系(包括:订购、取消、暂停、激活)的时候,通过此函数发起和 SP 的更新订购关系的交互。 79    /// </summary> 80    /// <param name="Version"> 81    /// 接口消息的版本号,目前接口消息的版本都为“1.5.0” 82    /// </param> 83    /// <param name="MsgType"> 84    /// 消息类型。 85    /// </param> 86    /// <param name="Send_Address"> 87    /// 发送方的地址。 88    /// </param> 89    /// <param name="Dest_Address"> 90    /// 接收方的地址。 91    /// </param> 92    /// <param name="FeeUser_ID"> 93    /// 计费用户标识。 94    /// </param> 95    /// <param name="DestUser_ID"> 96    /// 使用用户标识(当使用用户和计费用户为同一用户的时候,FeeUser_ID 和 DestUser_ID 的值相同)。 97    /// </param> 98    /// <param name="LinkID"> 99    /// 临时订购关系的事务 ID。 100    /// </param> 101    /// <param name="ActionID"> 102    /// 服务状态管理动作代码(1:开通服务;2:停止服务;3:激活服务;4:暂停服务)。 103    /// </param> 104    /// <param name="ActionReasonID"> 105    /// 产生服务状态管理动作原因的代码(1:用户发起行为;2:Admin&1860发起行为;3:Boss停机;4:Boss开机;5:Boss过户;6:Boss销户;7:Boss改号;8:扣费失败导致的服务取消;9:其他)。 106    /// </param> 107    /// <param name="SPID"> 108    /// SP 的企业代码。 109    /// </param> 110    /// <param name="SPServiceID"> 111    /// 业务标识,是数字、字母和符号的组合(长度为 10,SP的业务类型,数字、字母和符号的组合,由SP自定,如图片传情可定为TPCQ,股票查询可定义为11),也叫做计费代码。 112    /// </param> 113    /// <param name="AccessMode"> 114    /// 服务的访问方式(1:WEB;2:WAP;3:SMS)。 115    /// </param> 116    /// <param name="FeatureStr"> 117    /// 服务订购参数(base64加密),内容是长号码+空格+用户发送内容。 118    /// </param> 119    /// <param name="hRet"> 120    /// 返回值(0:成功;1:未知错误;2-99:保留;4000:无效的msgtype;4001:无效的action_id;4002:无效的action_reasonid;4003:无效的SP ID;4004:无效的serviceID;4005:无效的pseudocode;4006:无效的accessmode;4007:MISC 同步开通服务,但SP 端已存在订购关系,且状态为开通;4008:MISC 同步开通服务,且SP 端不存在订购关系,但开通服务失败;4009:MISC 同步开通服务,但SP 端已存在订购关系, 且状态为暂停;4010:MISC 同步停止服务, 且SP 端存在订购关系, 但取消服务失败;4011:MISC 同步停止服务, 但SP 端不存在订购关系;4012:MISC 同步暂停服务, 且SP 端存在订购关系, 但暂停服务失败;4013:MISC 同步暂停服务, 但SP 端不存在订购关系;4014:MISC 同步暂停服务, 但SP 端已存在订购关系, 且状态为暂停;4015:MISC 同步激活服务, 但SP 端已存在订购关系, 且状态为开通;4016:MISC 同步激活服务, 但SP 端不存在订购关系;4017:MISC 同步激活服务, 且SP 端存在订购关系, 但激活服务失败;9000:系统磁盘读写错误;9001:网络异常;9002:网络错误;9003:业务网关忙,业务网关缓存;9004:业务网关忙,并且业务网关缓冲区满,MISC 缓存,并暂时不要发送消息,等待一段时间重试;9005:MISC 忙,MISC 缓存;9006:MISC 忙,并且MISC 缓冲区满,业务网关缓存,并暂时不要发送消息,等待一段时间重试;9007:业务网关超过限制的流量;9008:MISC 异常,并不可用;9009:业务网关异常,并不可用;9010:该业务网关没有权限调用该接口消息;9011:MISC 没有权限发送该接口消息给业务网关;9012:版本不支持;9013:消息类型不对,系统不支持;9014:验证错误,无法解析SOAP 和XML 结构、缺少必须存在的字段,或者消息,格式不正确;9015:拒绝消息,服务器无法完成请求的服务)。 121    /// </param> 122    [WebMethod] 123    [SoapHeader("TransactionID", Direction = SoapHeaderDirection.InOut)] 124    [SoapDocumentMethod("sim.SyncOrderRelation", RequestElementName = "SyncOrderRelationReq", ResponseElementName = "SyncOrderRelationResp")] 125    [return: System.Xml.Serialization.SoapElementAttribute("return")] 126    [EditorBrowsable(EditorBrowsableState.Never)] 127    public void SyncOrderRelationReq( 128        ref string Version, 129        ref string MsgType, 130        AddressInfo Send_Address, 131        AddressInfo Dest_Address, 132        UserID FeeUser_ID, 133        UserID DestUser_ID, 134        string LinkID, 135        int ActionID, 136        int ActionReasonID, 137        string SPID, 138        string SPServiceID, 139        int AccessMode, 140        byte[] FeatureStr, 141        out int hRet) 142    { 143 144        Version = "1.5.0"; 145        MsgType = "SyncOrderRelationResp"; 146 147        OnSyncOrderRelationReq( 148            TransactionID == null ? null : TransactionID.ID, 149            Send_Address, 150            Dest_Address, 151            FeeUser_ID, 152            DestUser_ID, 153            LinkID, 154            ActionID, 155            ActionReasonID, 156            SPID, SPServiceID, 157            AccessMode, 158            FeatureStr, 159            out hRet); 160    } 161    #endregion 162 163}

Provision 类的 API

                       注意:asmx 页还是需要使用者自己建的,只需要将 asmx 的后台代码类继承 Provision 类,并实现抽象函数 OnSyncOrderRelationReq

                   可,在该抽象函数内,记录手机用户订购(或取消)业务的信息。

          3)对 PROVISION 反向订购/取消接口的支持:                    最后再简要地说一下关于对反向订购/取消的支持,我的实现就是对 dsmp.wsdl 这个 WEB 服务的一个简单封装。该 WEB 在移动的服务器上发               布。需要说明的是:根据反向订购/取消的业务流程,在这个过程中会执行正向订购/取消的那个 WEB 服务函数,因为反向订购/取消业务也会要求SP               接收一个 SyncOrderRelationReq 包并返回与其相应的 SyncOrderRelationResp 包。所以 PROVISION 实现的关键还是在 Provision 类。               下面是本文代码的下载链接:http://blogs.com/arcadiaray/CMPP30.rar

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多