public virtual void OnHttpStatusError(QQHttpResponse response) { var ex = new QQException(QQErrorCode.ErrorHttpStatus, response.ResponseMessage); if (!DoRetryIt(ex, QQConstants.MAX_RETRY_TIMES)) { // NotifyActionEvent(QQActionEventType.EVT_ERROR, ex); throw ex; } }
private bool DoRetryIt(QQException ex, int maxTimes) { if (ActionFuture.IsCanceled) { return(true); } if (++_retryTimes > maxTimes) { return(false); } NotifyActionEvent(QQActionEventType.EvtRetry, ex); Thread.Sleep(1000); Context.PushActor(new HttpActor(HttpActorType.BuildRequest, Context, this)); return(true); }
/// <summary> /// 反复轮询 /// </summary> /// <param name="sid">凭证ID,就算没有Cookie都可以轮询</param> /// <param name="t">邮件,好像是时间,用来消除轮询返回的列表中邮件,不然一直会返回那个邮件回来</param> private void LoopPoll(string sid, long t) { Poll(sid, t, (sender, Event) => { if (Event.Type == QQActionEventType.EVT_OK) { ErrorCount = 0; if (Event.Target == null) { // 没有新邮件,t直接传0 LoopPoll(sid, 0); } else { // 有新邮件 QQNotifyEvent evt = (QQNotifyEvent)Event.Target; // 通知事件 Context.FireNotify(evt); // 消除所有,传上最后t的标记上去 List <QQEmail> mailList = (List <QQEmail>)evt.Target; LoopPoll(sid, mailList[mailList.Count - 1].Flag); // 把邮件标记为已读,需要邮件列表ID // mark(false, mailList, null); } } else if (Event.Type == QQActionEventType.EVT_ERROR) { QQException ex = (QQException)Event.Target; if (ex.ErrorCode == QQErrorCode.INVALID_LOGIN_AUTH) { // 凭证失效,重新认证 DoPoll(); } else if (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { LoopPoll(sid, 0); ErrorCount++; } } }); }
protected Task <ActionEvent> NotifyErrorEventAsync(QQErrorCode code, string msg) { return(NotifyErrorEventAsync(QQException.CreateException(code, msg))); }
protected Task <ActionEvent> NotifyErrorEventAsync(QQException ex) { return(NotifyActionEventAsync(ActionEventType.EvtError, ex)); }
public override void OnHttpStatusOK(QQHttpResponse response) { var store = Context.Store; var notifyEvents = new List<QQNotifyEvent>(); var json = JObject.Parse(response.GetResponseString()); var retcode = json["retcode"].ToObject<int>(); if (retcode == 0) { //有可能为 {"retcode":0,"result":"ok"} if (json["result"] is JArray) { var results = json["result"].ToObject<JArray>(); // 消息下载来的列表中是倒过来的,那我直接倒过来取,编位回来 for (var i = results.Count - 1; i >= 0; i--) { var poll = results[i].ToObject<JObject>(); var pollType = poll["poll_type"].ToString(); var pollData = poll["value"].ToObject<JObject>(); switch (pollType) { case "input_notify": { var fromUin = pollData["from_uin"].ToObject<long>(); var qqBuddy = store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.BUDDY_INPUT, qqBuddy)); break; } case "message": { // 好友消息 notifyEvents.Add(ProcessBuddyMsg(pollData)); break; } case "group_message": { // 群消息 notifyEvents.Add(ProcessGroupMsg(pollData)); break; } case "discu_message": { // 讨论组消息 notifyEvents.Add(ProcessDiscuzMsg(pollData)); break; } case "sess_message": { // 临时会话消息 notifyEvents.Add(ProcessSessionMsg(pollData)); break; } case "shake_message": { // 窗口震动 var fromUin = pollData["from_uin"].ToObject<long>(); var user = Context.Store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.SHAKE_WINDOW, user)); break; } case "kick_message": { // 被踢下线 Context.Account.Status = QQStatus.OFFLINE; Context.Session.State = QQSessionState.KICKED; notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.KICK_OFFLINE, pollData["reason"].ToString())); break; } case "buddies_status_change": { // 群消息 notifyEvents.Add(ProcessBuddyStatusChange(pollData)); break; } case "system_message"://好友添加 { var processSystemMessage = ProcessSystemMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "group_web_message"://发布了共享文件 { var processSystemMessage = ProcessGroupWebMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "sys_g_msg"://被踢出了群 { var processSystemMessage = ProcessSystemGroupMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } default: { var ex = new QQException(QQErrorCode.UNKNOWN_ERROR, "unknown pollType: " + pollType); NotifyActionEvent(QQActionEventType.EVT_ERROR, ex); break; } } } } // end recode == 0 } else if (retcode == 102) { // 接连正常,没有消息到达 {"retcode":102,"errmsg":""} // 继续进行下一个消息请求 } else if (retcode == 110 || retcode == 109) { // 客户端主动退出 Context.Session.State = QQSessionState.OFFLINE; } else if (retcode == 116) { // 需要更新Ptwebqq值,暂时不知道干嘛用的 // {"retcode":116,"p":"2c0d8375e6c09f2af3ce60c6e081bdf4db271a14d0d85060"} // if (a.retcode === 116) alloy.portal.Ptwebqq = a.p) Context.Session.Ptwebqq = json["p"].ToString(); } else if (retcode == 121 || retcode == 120 || retcode == 100) { // 121,120 : ReLinkFailure 100 : NotRelogin // 服务器需求重新认证 // {"retcode":121,"t":"0"} /* LOG.info("**** NEED_REAUTH retcode: " + retcode + " ****");*/ MyLogger.Default.Info($"**** NEED_REAUTH retcode: {retcode} ****"); Context.Session.State = QQSessionState.OFFLINE; var ex = new QQException(QQErrorCode.INVALID_LOGIN_AUTH); NotifyActionEvent(QQActionEventType.EVT_ERROR, ex); return; //notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.NEED_REAUTH, null)); } else { // 返回错误,核心遇到未知recode // Context.Session.State = QQSessionState.ERROR); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.UNKNOWN_ERROR, json)); } NotifyActionEvent(QQActionEventType.EVT_OK, notifyEvents); }
/// <summary> /// 当轮询的返回成功时,获取返回的所有信息,如果没有则返回null /// </summary> /// <param name="result"></param> /// <returns></returns> private IList <QQNotifyEvent> GetAllMessagesWhenPollSuccess(JArray result) { var notifyEvents = new List <QQNotifyEvent>(); var results = result.ToObject <JArray>(); // 消息下载来的列表中是倒过来的,那我直接倒过来取,编位回来 for (var i = results.Count - 1; i >= 0; i--) { try { var poll = results[i].ToObject <JObject>(); var pollType = poll["poll_type"].ToString(); var pollData = poll["value"].ToObject <JObject>(); switch (pollType) { case "input_notify": { var fromUin = pollData["from_uin"].ToObject <long>(); var qqBuddy = Context.Store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.BuddyInput, qqBuddy)); break; } case "message": { // 好友消息 notifyEvents.Add(ProcessBuddyMsg(pollData)); break; } case "group_message": { // 群消息 notifyEvents.Add(ProcessGroupMsg(pollData)); break; } case "discu_message": { // 讨论组消息 notifyEvents.Add(ProcessDiscuzMsg(pollData)); break; } case "sess_message": { // 临时会话消息 notifyEvents.Add(ProcessSessionMsg(pollData)); break; } case "shake_message": { // 窗口震动 var fromUin = pollData["from_uin"].ToObject <long>(); var user = Context.Store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.ShakeWindow, user)); break; } case "kick_message": { // 被踢下线 Context.Account.Status = QQStatus.OFFLINE; Context.Session.State = QQSessionState.Kicked; notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.KickOffline, pollData["reason"].ToString())); break; } case "buddies_status_change": { // 群消息 notifyEvents.Add(ProcessBuddyStatusChange(pollData)); break; } case "system_message": //好友添加 { var processSystemMessage = ProcessSystemMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "group_web_message": //发布了共享文件 { var processSystemMessage = ProcessGroupWebMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "sys_g_msg": //被踢出了群 { var processSystemMessage = ProcessSystemGroupMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } default: { var ex = new QQException(QQErrorCode.UnknownError, "unknown pollType: " + pollType); NotifyActionEvent(QQActionEventType.EvtError, ex); break; } } } catch (Exception) { var ex = new QQException(QQErrorCode.JsonError); NotifyActionEvent(QQActionEventType.EvtError, ex); } } return(notifyEvents); }
public override void OnHttpStatusOK(QQHttpResponse response) { var store = Context.Store; var notifyEvents = new List <QQNotifyEvent>(); var json = JObject.Parse(response.GetResponseString()); var retcode = json["retcode"].ToObject <int>(); if (retcode == 0) { //有可能为 {"retcode":0,"result":"ok"} if (json["result"] is JArray) { var results = json["result"].ToObject <JArray>(); // 消息下载来的列表中是倒过来的,那我直接倒过来取,编位回来 for (var i = results.Count - 1; i >= 0; i--) { var poll = results[i].ToObject <JObject>(); var pollType = poll["poll_type"].ToString(); var pollData = poll["value"].ToObject <JObject>(); switch (pollType) { case "input_notify": { var fromUin = pollData["from_uin"].ToObject <long>(); var qqBuddy = store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.BUDDY_INPUT, qqBuddy)); break; } case "message": { // 好友消息 notifyEvents.Add(ProcessBuddyMsg(pollData)); break; } case "group_message": { // 群消息 notifyEvents.Add(ProcessGroupMsg(pollData)); break; } case "discu_message": { // 讨论组消息 notifyEvents.Add(ProcessDiscuzMsg(pollData)); break; } case "sess_message": { // 临时会话消息 notifyEvents.Add(ProcessSessionMsg(pollData)); break; } case "shake_message": { // 窗口震动 var fromUin = pollData["from_uin"].ToObject <long>(); var user = Context.Store.GetBuddyByUin(fromUin); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.SHAKE_WINDOW, user)); break; } case "kick_message": { // 被踢下线 Context.Account.Status = QQStatus.OFFLINE; Context.Session.State = QQSessionState.KICKED; notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.KICK_OFFLINE, pollData["reason"].ToString())); break; } case "buddies_status_change": { // 群消息 notifyEvents.Add(ProcessBuddyStatusChange(pollData)); break; } case "system_message": //好友添加 { var processSystemMessage = ProcessSystemMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "group_web_message": //发布了共享文件 { var processSystemMessage = ProcessGroupWebMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } case "sys_g_msg": //被踢出了群 { var processSystemMessage = ProcessSystemGroupMsg(pollData); if (processSystemMessage != null) { notifyEvents.Add(processSystemMessage); } break; } default: { var ex = new QQException(QQErrorCode.UNKNOWN_ERROR, "unknown pollType: " + pollType); NotifyActionEvent(QQActionEventType.EVT_ERROR, ex); break; } } } } // end recode == 0 } else if (retcode == 102) { // 接连正常,没有消息到达 {"retcode":102,"errmsg":""} // 继续进行下一个消息请求 } else if (retcode == 110 || retcode == 109) { // 客户端主动退出 Context.Session.State = QQSessionState.OFFLINE; } else if (retcode == 116) { // 需要更新Ptwebqq值,暂时不知道干嘛用的 // {"retcode":116,"p":"2c0d8375e6c09f2af3ce60c6e081bdf4db271a14d0d85060"} // if (a.retcode === 116) alloy.portal.Ptwebqq = a.p) Context.Session.Ptwebqq = json["p"].ToString(); } else if (retcode == 121 || retcode == 120 || retcode == 100) { // 121,120 : ReLinkFailure 100 : NotRelogin // 服务器需求重新认证 // {"retcode":121,"t":"0"} /* LOG.info("**** NEED_REAUTH retcode: " + retcode + " ****");*/ MyLogger.Default.Info($"**** NEED_REAUTH retcode: {retcode} ****"); Context.Session.State = QQSessionState.OFFLINE; var ex = new QQException(QQErrorCode.INVALID_LOGIN_AUTH); NotifyActionEvent(QQActionEventType.EVT_ERROR, ex); return; //notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.NEED_REAUTH, null)); } else { // 返回错误,核心遇到未知recode // Context.Session.State = QQSessionState.ERROR); notifyEvents.Add(new QQNotifyEvent(QQNotifyEventType.UNKNOWN_ERROR, json)); } NotifyActionEvent(QQActionEventType.EVT_OK, notifyEvents); }
/// <summary> /// 轮询邮件信息 先通过pt4获取check url 再通过check检查登录验证 再通过login获取key2 /// 再通过wpkey获取key3 然后得到wpkey,进行邮件轮询 /// </summary> internal void DoPoll() { // 步骤四 QQActionEventHandler wpkeyListener = (sender, Event) => { if (Event.Type == QQActionEventType.EVT_OK) { ErrorCount = 0; // 跳到轮询 LoopPoll(Event.Target.ToString(), 0); } else if (Event.Type == QQActionEventType.EVT_ERROR) { while (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { if (GetPT4Auth(null).WaitFinalEvent(3000).Type != QQActionEventType.EVT_OK) { ErrorCount++; } else { ErrorCount = 0; // 跳到轮询 LoopPoll(Event.Target.ToString(), 0); } } } }; // 步骤三 QQActionEventHandler loginListener = (sender, Event) => { if (Event.Type == QQActionEventType.EVT_OK) { ErrorCount = 0; // 跳到步骤四 string key = Event.Target.ToString(); GetWPKey(key, wpkeyListener); Context.Session.EmailAuthKey = key; } else if (Event.Type == QQActionEventType.EVT_ERROR) { while (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { if (GetPT4Auth(null).WaitFinalEvent(3000).Type != QQActionEventType.EVT_OK) { ErrorCount++; } else { ErrorCount = 0; // 跳到步骤四 string key = Event.Target.ToString(); GetWPKey(key, wpkeyListener); Context.Session.EmailAuthKey = key; } } } }; // 步骤二 QQActionEventHandler checkListener = (sender, Event) => { if (Event.Type == QQActionEventType.EVT_OK) { ErrorCount = 0; // 跳到步骤三 Login(loginListener); } else if (Event.Type == QQActionEventType.EVT_ERROR) { while (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { if (GetPT4Auth(null).WaitFinalEvent(3000).Type != QQActionEventType.EVT_OK) { ErrorCount++; } else { ErrorCount = 0; // 跳到步骤三 Login(loginListener); } } } }; // 步骤一 QQActionEventHandler pt4Listener = (sender, Event) => { if (Event.Type == QQActionEventType.EVT_OK) { ErrorCount = 0; // 跳到步骤二 Check(Event.Target.ToString(), checkListener); } else if (Event.Type == QQActionEventType.EVT_ERROR) { while (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { if (GetPT4Auth(null).WaitFinalEvent(3000).Type != QQActionEventType.EVT_OK) { QQException ex = (QQException)Event.Target; if (ex.ErrorCode == QQErrorCode.INVALID_LOGIN_AUTH) { // 登录失败,QQ消息的POLL同时也失效,这时那边会重新登录 // 如果已经在登录中,或者已经登录了,就不用再次执行 MyLogger.Default.Warn("GetPT4Auth error!!! wait Relogin...", ex); QQSession session = Context.Session; if (session.State == QQSessionState.LOGINING || session.State == QQSessionState.KICKED) { return; } ProcModule procModule = Context.GetModule <ProcModule>(QQModuleType.PROC); procModule.Relogin();// 重新登录成功会重新唤醒beginPoll } else if (ErrorCount < QQConstants.MAX_POLL_ERR_CNT) { ErrorCount++; } } else { ErrorCount = 0; // 跳到步骤二 Check(Event.Target.ToString(), checkListener); } } } }; GetPT4Auth(pt4Listener); }
private bool DoRetryIt(QQException ex, int maxTimes) { if (ActionFuture.IsCanceled) return true; if (++_retryTimes > maxTimes) return false; NotifyActionEvent(QQActionEventType.EvtRetry, ex); Thread.Sleep(1000); Context.PushActor(new HttpActor(HttpActorType.BuildRequest, Context, this)); return true; }