/// <summary> /// 推送消息 /// </summary> /// <param name="sendProcessDto">推送消息</param> /// <param name="rzTokenBrandDto">注册信息</param> /// <param name="retMsg"></param> /// <returns></returns> public bool SendNewProcess(SendProcessDto sendProcessDto, DeviceChannelDto deviceChannelDto, out string retMsg) { Stopwatch stop = new Stopwatch(); retMsg = string.Empty; if (sendProcessDto == null || deviceChannelDto == null) { retMsg = "SendProcessDto或DeviceChannelDto为空"; return(false); } stop.Start(); //底层发送消息 int requestTime; var senderRet = SendPushMsgToProvider(sendProcessDto, deviceChannelDto, out requestTime); stop.Stop(); //LogHelper.Info.Write("SendNewProcess", string.Format("SendPushMsgToProvider \r\n SystemType:{0},TimeSpan:{1}", deviceChannelDto.SystemType.ToString(), stop.ElapsedMilliseconds.ToString())); stop.Restart(); //执行Db操作 SendMsgToDB(senderRet, sendProcessDto, deviceChannelDto, requestTime); stop.Stop(); //LogHelper.Info.Write("SendNewProcess", string.Format("SendMsgToDB \r\n SystemType:{0},TimeSpan:{1}", deviceChannelDto.SystemType.ToString(), stop.ElapsedMilliseconds.ToString())); //推送成功 return(true); }
/// <summary> /// 处理数据传给DB /// 将消息一拆为n个消息 /// </summary> /// <param name="model"></param> private void HandleMsgToDB(object model) { //var _logger = _loggerFactory.CreateLogger<MsgService>(); using (var scope = SherlockEngine.Current.CreateScope()) { try { string serialNO = Guid.NewGuid().ToString();//同一条消息进行拆解 SendMsgRequest sendMsgRequest = (SendMsgRequest)model; //将推送消息推送消息中心 PushMessageToMessageCenter(sendMsgRequest); //拆分数据 //获取设备和通道 IPushTokenBrandService pushTokenBrandService = scope.ServiceProvider.GetService(typeof(IPushTokenBrandService)) as IPushTokenBrandService; List <DeviceChannelDomainModel> deviceChannelDomainModelList = pushTokenBrandService.GetDeviceChannelListAsync(sendMsgRequest.Token, sendMsgRequest.AppId).Result; List <DeviceChannelDto> deviceChannelList = _mapper.Map <List <DeviceChannelDto> >(deviceChannelDomainModelList); //未获取到,接收的消息直接进历史表,标记为账号登出 if (deviceChannelList == null || deviceChannelList.Count == 0) { //直接入历史表,标记错误 SendProcessDto sendProcessDto = SendMsgToSendProcess(sendMsgRequest, serialNO); sendProcessDto.Token = sendMsgRequest.Token; ISendProcessLogic sendProcessLogic = scope.ServiceProvider.GetService(typeof(ISendProcessLogic)) as ISendProcessLogic; sendProcessLogic.RecordErrorProcess(sendProcessDto, ErrorTypeEnum.Logout, string.Empty); return; } //获取到,根据设备Token拆分数据 List <SendProcessDto> sendProcessDtoList = new List <SendProcessDto>(); foreach (var item in deviceChannelList) { SendProcessDto sendProcessDto = SendMsgToSendProcess(sendMsgRequest, serialNO); sendProcessDto.Token = sendMsgRequest.Token; //将获取到的TokenBrandId(核心),BrandId,ChannelId,DeviceToken 赋给对象,可做到新老接口兼容 //老接口发送数据时,可根据TokenBrandId直接找到需要发送的ChannelId和DeviceToken //新接口发送数据时,通过ChannelId,DeviceToken 发送数据 sendProcessDto.TokenBrandId = item.Id; sendProcessDto.BrandId = item.BrandId; sendProcessDto.ChannelId = item.ChannelId; sendProcessDto.DeviceToken = item.DeviceToken; sendProcessDtoList.Add(sendProcessDto); } IMapper mapper = scope.ServiceProvider.GetService(typeof(IMapper)) as IMapper; List <PushSendProcessDomainModel> domainList = mapper.Map <List <PushSendProcessDomainModel> >(sendProcessDtoList); IPushSendProcessService pushSendProcessService = scope.ServiceProvider.GetService(typeof(IPushSendProcessService)) as IPushSendProcessService; int rows = pushSendProcessService.InsertProcessListAsync(domainList).Result; } catch (Exception ex) { //_logger.LogError(ex.Message.ToString()); //LogHelper.Error.Write("HandleMsgToDB", ex); } finally { _semaphore.Release(); //LogHelper.Info.Write("HandleMsgToDB", "信号量释放之前使用的数量:" + count); } } }
/// <summary> /// 推送消息给推送平台 /// </summary> /// <param name="sendProcessDto">推送消息</param> /// <param name="rzTokenBrandDto">注册信息</param> /// <param name="rzTokenBrandDetailDto">注册明细</param> /// <param name="channelDto">通道</param> /// <param name="appChannelDto">App和通道的关系</param> /// <param name="requestTime">请求时间</param> /// <returns></returns> public SenderRet SendPushMsgToProvider(SendProcessDto sendProcessDto, DeviceChannelDto deviceChannelDto, out int requestTime) { SenderRet senderRet = new SenderRet { IsSuccess = true }; //底层发送消息 requestTime = 0; //获取ProductionMode object ProducttMode = _configLogic.GetConfigValue(ConfigKey.ProductionMode); //构造底层推送消息的参数 PushChannelModel pushChannelModel = new PushChannelModel { ChannelName = deviceChannelDto.ChannelName, Url = deviceChannelDto.Url, AppKey = deviceChannelDto.AppKey, AppSecret = deviceChannelDto.AppSecret, ProductionMode = Convert.ToBoolean(ProducttMode) //获取调试模式 }; PushMsgModel pushMsgModel = new PushMsgModel { Ticker = sendProcessDto.Title, Title = sendProcessDto.Title, Msg = sendProcessDto.Msg, AttachInfo = sendProcessDto.AttachInfo, DeviceToken = deviceChannelDto.DeviceToken, SystemType = (SystemTypeEnum)deviceChannelDto.SystemType }; ISender sender = PushSenderManager.GetSender(deviceChannelDto.ChannelId); if (sender == null) { senderRet.IsSuccess = false; senderRet.Msg = string.Format("ChannelId:{0},推送信息供应商不存在", deviceChannelDto.ChannelId); //LogHelper.Error.Write("SendPushMsgToProvider", senderRet.Msg); return(senderRet); } Stopwatch sw = new Stopwatch(); var isRealPushMsg = _configLogic.GetConfigValue(ConfigKey.IsRealPushMsg); sw.Start(); if (isRealPushMsg != null && Convert.ToBoolean(isRealPushMsg)) { senderRet = PushSender.Send(sender, pushChannelModel, pushMsgModel); } else { Thread.Sleep(200); senderRet = new SenderRet { IsSuccess = true, Sign = Guid.NewGuid().ToString() }; } sw.Stop(); requestTime = (int)sw.ElapsedMilliseconds; return(senderRet); }
/// <summary> /// 处理方法 /// </summary> /// <param name="process"></param> public bool Handle(SendProcessDto process, out string retMsg) { ProcessHistoryDto processHistoryDto = _mapper.Map<ProcessHistoryDto>(process); processHistoryDto.Id = 0; processHistoryDto.SendStatus = (int)SendStatusEnum.Failure; processHistoryDto.ErrorType = (int)ErrorTypeEnum.TimeOut; AddProcessHistoryDomainModel model = _mapper.Map<AddProcessHistoryDomainModel>(processHistoryDto); int row = _pushProcessHistoryService.InsertProcessHistoryAsync(model).Result; row = _pushSendProcessService.DeleteProcessByIdAsync(process.Id).Result; retMsg = ""; return true; }
/// <summary> /// 推送消息之后执行DB操作 /// </summary> /// <param name="senderRet">发送记录</param> /// <param name="sendProcessDto">推送消息</param> /// <param name="rzTokenBrandDto">注册信息</param> /// <param name="rzTokenBrandDetailDto">注册明细</param> /// <param name="channelDto">通道</param> /// <param name="requestTime">执行时间</param> public void SendMsgToDB(SenderRet senderRet, SendProcessDto sendProcessDto, DeviceChannelDto deviceChannelDto, int requestTime) { if (!senderRet.IsSuccess) { //发送失败的逻辑 DateTime sendTime = DateTime.Now.AddSeconds((sendProcessDto.EndTime - DateTimeHelper.GetNow()).TotalSeconds / 2); if (sendProcessDto.TokenBrandId.HasValue) { int row = _pushSendProcessService.WriteBackProcessByIdAsync(sendProcessDto.Id, sendTime).Result; } else { //重新制造RzTokenBrandId有值的推送信息 SendProcessDto newSendProcess = sendProcessDto; newSendProcess.Id = 0; newSendProcess.TokenBrandId = deviceChannelDto.Id; newSendProcess.SendTime = sendTime; newSendProcess.IsUsed = false; newSendProcess.DelayTimes = newSendProcess.DelayTimes + 1; PushSendProcessDomainModel pushSendProcessDomainModel = _mapper.Map <PushSendProcessDomainModel>(newSendProcess); int row = _pushSendProcessService.InsertProcessAsync(pushSendProcessDomainModel).Result; } } else if (sendProcessDto.TokenBrandId.HasValue) { //发送成功并且RzTokenBrandId不为空,直接删掉待发送的数据 int row = _pushSendProcessService.DeleteProcessByIdAsync(sendProcessDto.Id).Result; } //无论发送成功与否,都要插入历史记录 ProcessHistoryDto processHistoryDto = _mapper.Map <ProcessHistoryDto>(sendProcessDto); processHistoryDto.Id = 0; processHistoryDto.SendTime = DateTimeHelper.GetNow(); if (senderRet.IsSuccess) { processHistoryDto.SendStatus = (int)SendStatusEnum.Success; } else { processHistoryDto.SendStatus = (int)SendStatusEnum.Failure; processHistoryDto.ErrorType = (int)ErrorTypeEnum.PushPlatform; } processHistoryDto.ChannelId = deviceChannelDto.ChannelId; processHistoryDto.BrandId = deviceChannelDto.BrandId; processHistoryDto.RequestTime = requestTime; processHistoryDto.ReturnSign = senderRet.Sign; processHistoryDto.Remark = senderRet.Code; AddProcessHistoryDomainModel model = _mapper.Map <AddProcessHistoryDomainModel>(processHistoryDto); int res = _pushProcessHistoryService.InsertProcessHistoryAsync(model).Result; }
/// <summary> /// 对推送信息分类 /// </summary> /// <param name="process"></param> /// <returns>1:超时,2:重试超过3次,3:正常发送</returns> private int ClassifyProcess(SendProcessDto process) { var now = DateTimeHelper.GetNow(); if (process.EndTime < now) { return(1); } if (process.DelayTimes >= 3) { return(2); } return(3); }
/// <summary> /// 轮询推送消息 /// </summary> /// <param name="processId"></param> /// <param name="ret"></param> /// <returns></returns> public ErrCode SendMsg(long processId, out string ret) { ret = ""; int rows = _pushSendProcessService.UpdateProcessUseStatusByIdAsync(processId, DateTimeHelper.GetNow().AddMinutes(2)).Result; if (rows == 0) { ret = "已被其他机器处理"; return(ErrCode.PermissionDenied); } PushSendProcessDomainModel pushSendProcessDomainModel = _pushSendProcessService.GetProcessByIdAsync(processId).Result; SendProcessDto process = _mapper.Map <SendProcessDto>(pushSendProcessDomainModel); var classify = ClassifyProcess(process); try { bool flag = false; switch (classify) { case 1: flag = _timeOutHandler.Handle(process, out ret); break; case 2: flag = _retryTimesOverHandler.Handle(process, out ret); break; case 3: flag = _sendHandler.Handle(process, out ret); break; default: ret = "该分类处理没有实现"; break; } if (!flag) { return(ErrCode.Failure); } } catch (Exception ex) { //LogHelper.Error.Write("SendProcess", ex); ret = ex.StackTrace + "\r\n" + ex.Message; return(ErrCode.Failure); } return(ErrCode.Sucess); }
/// <summary> /// 备案错误推送消息 /// </summary> /// <param name="sendProcessDto">推送消息</param> /// <param name="errorStatus">错误类型</param> /// <param name="errorRemark">错误信息</param> /// <returns></returns> public void RecordErrorProcess(SendProcessDto sendProcessDto, ErrorTypeEnum errorType, string errorRemark) { if (sendProcessDto == null) { //LogHelper.Error.Write("RecordErrorProcess", "参数错误"); return; } ProcessHistoryDto processHistoryDto = _mapper.Map <ProcessHistoryDto>(sendProcessDto); processHistoryDto.Id = 0; processHistoryDto.SendStatus = (int)SendStatusEnum.Failure; processHistoryDto.ErrorType = (int)errorType; processHistoryDto.Remark = errorRemark; AddProcessHistoryDomainModel model = _mapper.Map <AddProcessHistoryDomainModel>(processHistoryDto); int row = _pushProcessHistoryService.InsertProcessHistoryAsync(model).Result; }
/// <summary> /// 将sendMsgDto转为SendMsgToSendProcess,并赋值参数 /// </summary> /// <param name="sendMsgDto"></param> /// <returns></returns> private SendProcessDto SendMsgToSendProcess(SendMsgDto sendMsgDto, string serialNO) { sendMsgDto.StartTime = sendMsgDto.StartTime.HasValue ? sendMsgDto.StartTime : DateTimeHelper.GetNow(); SendProcessDto sendProcessDto = _mapper.Map <SendProcessDto>(sendMsgDto); sendProcessDto.AttachInfo = sendMsgDto.AttachInfo == null ? null : JsonConvert.SerializeObject(sendMsgDto.AttachInfo); sendProcessDto.SerialNo = serialNO; sendProcessDto.PriorityLevel = (int)PriorityLevelEnum.Middle;//默认优先级为中 sendProcessDto.StartTime = sendMsgDto.StartTime.Value; sendProcessDto.EndTime = sendMsgDto.Timeliness.HasValue ? sendProcessDto.StartTime.AddMinutes(sendMsgDto.Timeliness.Value) : sendProcessDto.StartTime.AddMinutes(24 * 60); sendProcessDto.IsUsed = false; sendProcessDto.ExpireTime = sendProcessDto.StartTime; sendProcessDto.SendTime = sendProcessDto.StartTime; sendProcessDto.DelayTimes = 0; return(sendProcessDto); }
public bool Handle(SendProcessDto process, out string retMsg) { retMsg = string.Empty; //判断RzTokenBrandId是否为空 if (process.TokenBrandId.HasValue) { DeviceChannelDomainModel deviceChannelDomainModel = _pushTokenBrandService.GetDeviceChannelListByTokenBrandIdAsync(process.TokenBrandId.Value).Result; DeviceChannelDto deviceChannelDto = _mapper.Map <DeviceChannelDto>(deviceChannelDomainModel); if (deviceChannelDomainModel != null) { //如果存在RzTokenBrandId _sendProcessLogic.SendNewProcess(process, deviceChannelDto, out retMsg); return(true); } //如果不存在RzTokenBrandId,执行下面操作 } List <DeviceChannelDomainModel> deviceChannelList = _pushTokenBrandService.GetDeviceChannelListAsync(process.Token, process.AppId).Result; if (deviceChannelList == null || deviceChannelList.Count == 0) { _sendProcessLogic.RecordErrorProcess(process, ErrorTypeEnum.Logout, retMsg); } else { foreach (var item in deviceChannelList) { DeviceChannelDto deviceChannelDto = _mapper.Map <DeviceChannelDto>(item); _sendProcessLogic.SendNewProcess(process, deviceChannelDto, out retMsg); } } //发送成功删除数据 var i = _pushSendProcessService.DeleteProcessByIdAsync(process.Id).Result; return(true); }