/// <summary> /// Отправка первого сообщения из очереди сообщений /// </summary> /// <param name="fTest"> /// Если True, то метод был вызван после окончания ожидания, в случае неудачи следует уменьшить /// количество оставшихся попыток /// </param> public void SendMessage(bool fTest) { CometServer.WriteLog("Start SendMessage"); if (Messages == null) { CometServer.WriteLog("End SendMessage: Messages == null"); return; } if (Messages.Count < 1) { CometServer.WriteLog("End SendMessage: Messages.Count < 1"); return; } var fFail = true; if (CurrentContext != null && CurrentContext.Session != null) { var message = Messages.Peek(); try { // пишем в выходной поток текущее сообщение CometServer.WriteLog($"SendMessage: {message.Message}"); CurrentContext.Response.Write(message.IsV4Script ? message.Message : message.Serialize()); Messages.Dequeue(); fFail = false; //Сбрасываем счетчик неудачных попыток после каждой успешной отправки сообщения, если клиент не должен быть удален (например после Unregister) if (Tries > 0) { Tries = MaxTries; } } catch { } } // После чего завершаем запрос - вот именно после этого результаты // запроса пойдут ко всем подключенным клиентам CompleteRequest(); CurrentContext = null; if (fFail && fTest && --Tries < 1) { Messages = null; } CometServer.WriteLog("End SendMessage"); }
// Завершим запрос public void CompleteRequest() { // При завершении запроса просто выставим флаг что он завершен // и вызовем callback CometServer.WriteLog("Start CompleteRequest"); IsCompleted = true; if (AsyncCallback != null) { try { AsyncCallback(this); } catch { } } CometServer.WriteLog("End CompleteRequest"); }
/// <summary> /// Добавить сообщение в очередь /// </summary> /// <param name="m"></param> public int AddMessage(CometMessage m) { //Клиент уже разрегистрирован if (Tries < 1) { return(-1); } CometServer.WriteLog("Start AddMessage"); if (null == Messages) { Messages = new Queue <CometMessage>(); } if (Messages.Count < 1) { Tries = MaxTries; } //Если в очереди уже есть сообщение для обновления списка пользователей, то имеющееся сообщение можно просто обновить if (m.isUserList()) { var en = Messages.GetEnumerator(); while (en.MoveNext()) { if (en.Current.isUserList()) { CometServer.WriteLog($"AddMessage: {m.Message}"); en.Current.Message = m.Message; return(Messages.Count); } } } CometServer.WriteLog($"AddMessage: {m.Message}"); Messages.Enqueue(m); CometServer.WriteLog("End AddMessage"); return(Messages.Count); }
// Основная функция рабочего потока private void RequestWorker(object obj) { // obj - второй параметр при вызове ThreadPool.QueueUserWorkItem() var state = obj as CometAsyncState; if (state == null) { return; } var command = ""; var guid = ""; var message = ""; var isEditable = false; var id = 0; var name = ""; try { message = state.CurrentContext.Request.QueryString["message"]; } catch { // ignored } finally { command = state.CurrentContext.Request.QueryString["cmd"]; guid = state.CurrentContext.Request.QueryString["guid"]; isEditable = state.CurrentContext.Request.QueryString["Editable"] == "true"; id = int.Parse(state.CurrentContext.Request.QueryString["id"] ?? "0"); name = state.CurrentContext.Request.QueryString["name"]; } state.IsEditable = isEditable; state.Id = id; state.Name = name; switch (command) { //case "register": // // Регистрируем клиента в очереди сообщений // state.ClientGuid = guid; // CometServer.RegisterClient(state); // state.CompleteRequest(); // break; //case "unregister": // // Удаляем клиента из очереди сообщений // state.ClientGuid = guid; // CometServer.UnregisterClient(state); // state.CompleteRequest(); // break; //case "connect": // if (guid != null) // CometServer.UpdateClient(state, guid, true); // break; case "update": CometServer.WriteLog("RequestWorkerDefault: command -> " + command + " " + guid); CometServer.PushMessage( new CometMessage { Message = "", UserName = "", Status = 0, ClientGuid = guid }, guid); state.CompleteRequest(); break; case "send": // Отправка сообщения var data = new StreamReader(state.CurrentContext.Request.InputStream).ReadToEnd(); if (data.Length > 0) { var jdata = new JavaScriptSerializer().Deserialize <Dictionary <string, string> >(data); message = HttpUtility.UrlDecode(jdata["message"]); } state.CompleteRequest(); CometServer.OnNotifyMessage(id.ToString(), name, guid, message); break; default: CometServer.WriteLog("RequestWorkerDefault: command -> " + command + " " + guid); // При реконнекте клиента if (guid != null) { CometServer.UpdateClient(state, guid); } break; } CometServer.Process(); }