/// <summary> /// 针对响应数据回调处理 /// </summary> /// <param name="cmConOpt"></param> /// <param name="command"></param> private static void RespCallBack(CmppConnectionOption cmConOpt, CmppCommand command) { //LogUtil.Info("接收运营商响应信息", command, CompModuleLogs.SmsExchangeRespLog); if (command.Response.MsgHeader.CommandType == CommandType.ConnectResp) { var resp = command.Response as ConnectResp; if (resp != null) { var result = resp.GetResult(); if (result.Ret == ResultTypes.Success) { LogUtil.Info("建立连接成功!", "connect_success"); } else { LogUtil.Info(result.Message, "connect_failed"); } } } else if (command.Response.MsgHeader.CommandType != CommandType.ActiveTestResp && command.Response.MsgHeader.CommandType != CommandType.ActiveTest) { if (cmConOpt.CallBack != null) { AsynUtil.Asyn(obj => { var com = obj.Item2; var opt = obj.Item1; opt.CallBack(com); }, Tuple.Create(cmConOpt, command)); } } }
/// <summary> /// 写socket字节流部分 /// </summary> /// <param name="cmConOpt"></param> /// <param name="socket"></param> private static void WriteSocketReq(CmppConnectionOption cmConOpt, Socket socket) { try { // 1. 发送请求 var command = cmConOpt.CommandQueue.Dequeue(); socket.Send(command.Request.ToBytes()); // 2. 记录当前请求时间 command.LastSendTime = cmConOpt.LastExcuteTime = DateTime.Now; // 3. 添加等待响应请求 if (command.Request.MsgHeader.CommandType == CommandType.ActiveTestResp || command.Request.MsgHeader.CommandType == CommandType.DeliverResp) { cmConOpt.WaitingCommand.Add(command.Request.MsgHeader.SequenceId, command); } } catch (Exception ex) { LogUtil.Info("发送短信运营方信息时出错"); #if DEBUG throw ex; #endif } }
/// <summary> /// 打开socket链接 /// </summary> private ResultModel OpenSocketConnect(CmppConnectionOption opt) { try { if (!_socket.Connected) { _socket.Connect(opt.IpAddress, opt.Port); } var connectReq = new ConnectReq(opt.SpCode, opt.Pwd, Option.Version); connectReq.MsgHeader.SequenceId = GetNextSequenceId(); _socket.Send(connectReq.ToBytes()); opt.ConnectedStatu = ConnectionStatu.Waiting; LogUtil.Info("发送打开连接请求", "connect_req"); } catch (Exception ex) { var keyCode = LogUtil.Error(string.Concat("连接短信服务方异常失败,详情:", ex.Message), "connect_failed"); opt.ConnectedStatu = ConnectionStatu.Failed; return(new ResultModel(ResultTypes.InnerError, string.Concat("连接短信服务方失败,错误码:", keyCode))); } return(new ResultModel()); }
/// <summary> /// 清理过期请求 /// </summary> /// <param name="cmConOpt"></param> /// <returns></returns> private static void RemoveExpireCommand(CmppConnectionOption cmConOpt) { if ((DateTime.Now - cmConOpt.LastExcuteTime).TotalSeconds > 20 && cmConOpt.WaitingCommand.Count > 0) { List <uint> removeSeqIds = null; foreach (var wcom in cmConOpt.WaitingCommand) { if ((DateTime.Now - wcom.Value.LastSendTime).TotalSeconds > 30) { // 放在这里避免多次创建无效变量 if (removeSeqIds == null) { removeSeqIds = new List <uint>(); } removeSeqIds.Add(wcom.Key); } } if (removeSeqIds != null && removeSeqIds.Count > 0) { removeSeqIds.ForEach(cmSeqId => { cmConOpt.WaitingCommand.Remove(cmSeqId); }); } } }
/// <summary> /// 读处理 /// </summary> /// <param name="socket"></param> /// <param name="cmConOpt"></param> private static void ReadSocketResp(Socket socket, CmppConnectionOption cmConOpt) { try { var resp = GetSocketResp(socket); // 1. 获取上次发送请求command CmppCommand command = null; if (cmConOpt.WaitingCommand.ContainsKey(resp.MsgHeader.SequenceId)) { command = cmConOpt.WaitingCommand[resp.MsgHeader.SequenceId]; cmConOpt.WaitingCommand.Remove(resp.MsgHeader.SequenceId); } else { command = new CmppCommand(); } command.Response = resp; // 2. 激活测试 if (resp.MsgHeader.CommandType == CommandType.ActiveTest) { // 对方发送activetest 给出响应 cmConOpt.CommandQueue.Enqueue(new CmppCommand() { Request = new ActiveTestResp(resp.MsgHeader.SequenceId) }); } // 3. 连接结果响应 else if (resp.MsgHeader.CommandType == CommandType.ConnectResp) { var conResp = resp as ConnectResp; cmConOpt.ConnectedStatu = conResp.Status == 0 ? ConnectionStatu.Success : ConnectionStatu.Failed; } // 4. 对响应设置回调处理 RespCallBack(cmConOpt, command); } catch (Exception ex) { LogUtil.Info("接收运营商响应信息时出错", "sendreq_error"); #if DEBUG throw ex; #endif } }
/// <summary> /// 判断当前是否具备可写 /// 是否已经大于滑动窗口数量,是否超过时间限制 /// </summary> /// <param name="opt"></param> /// <returns></returns> private bool CheckCanWrite(CmppConnectionOption opt) { bool isOkay = false; if (opt.ConnectedStatu == ConnectionStatu.Success && opt.MaxSecondSpeed > 0) { isOkay = opt.CommandQueue.Count > 0 && opt.WaitingCommand.Count < opt.SlidCount; if (isOkay) { int seprateMilliSecond = 1000 / opt.MaxSecondSpeed; isOkay = (DateTime.Now - opt.LastExcuteTime).Milliseconds > seprateMilliSecond; } } return(isOkay); }
/// <summary> /// 构造函数 /// </summary> /// <param name="ipAddress"></param> /// <param name="port"></param> /// <param name="spCode">企业代码</param> /// <param name="pwd">密码</param> /// <param name="spId">企业号码(手机号显示主号)</param> /// <param name="opt"> 链接其他设置信息 </param> public CmppConnection(string ipAddress, int port, string spCode, string pwd, string spId, CmppConnectionOption opt = null) { Option = opt ?? new CmppConnectionOption(); Option.IpAddress = ipAddress; Option.Port = port; Option.SpCode = spCode; Option.Pwd = pwd; Option.SpId = spId; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); }