// Регистрация клиента public static void RegisterClient(CometAsyncState state, bool notifyClients = true) { WriteLog("+++++++++++++++++++++++++++++++++++++++++++++++++++++"); WriteLog("Start RegisterClient by CometAsyncState -> " + state.ClientGuid + " notifyClients ->" + notifyClients); lock (SyncLock) { // Присваиваем гуид и добавляем в список if (!Connections.Exists(x => x.ClientGuid == state.ClientGuid)) { Connections.Add(state); } WriteLog("EXISTS CONNECTIONS:"); foreach (var clientState in Connections) { WriteLog( $" -> ClientGuid: {clientState.ClientGuid} Tries: {clientState.Tries} StartSession: {clientState.Start.ToLongTimeString()}"); } } if (notifyClients) { OnNotifyClients(state, state.ClientGuid); } WriteLog( $"End RegisterClient by CometAsyncState -> ClientGuid:{state.ClientGuid} NotifyClients: {notifyClients}"); }
// Разрегистрация клиента public static void UnregisterClient(CometAsyncState client, bool reload = false) { WriteLog($"Start UnregisterClient by CometAsyncState -> ClientGuid: {client.ClientGuid} Reload: {reload}"); var m = new CometMessage { Message = "unregister", UserName = client.CurrentContext.User.Identity.Name, Status = 1, Reload = reload ? 1 : 0, ClientGuid = client.ClientGuid }; lock (SyncLock) { //Очередь сообщений очищаем, клиент уже не хочет ничего принимать if (null != client.Messages) { client.Messages.Clear(); } client.AddMessage(m); // Клиент будет удален из списка после отправки последнего сообщения ему client.Tries = 0; } if (client.Id > 0) { OnNotifyClients(client, null, 1); } Process(); }
public IAsyncResult BeginProcessRequest(HttpContext ctx, AsyncCallback cb, object obj) { // Готовим объект для передачи его в QueueUserWorkItem var currentAsyncState = new CometAsyncState(ctx, cb, obj); RequestWorker(currentAsyncState); return(currentAsyncState); }
/// <summary> /// Событие, отслеживающие необходимость уведомления клиентов /// </summary> /// <param name="state">Объект-подключения</param> /// <param name="clientGuid">Идентификатор страницы</param> /// <param name="status">Статус собфтия</param> private static void OnNotifyClients(CometAsyncState state, string clientGuid = null, int status = 0) { if (NotifyClients != null) { if (clientGuid == null && state == null || clientGuid == null && state != null && state.ClientGuid == null) { return; } NotifyClients(state, clientGuid, status); } }
/// <summary> /// Срабатывает кажды раз при запуске клиентом очережного запроса Long poll /// так как при этом HttpContext клиента изменяется, то надо обновить /// все изменившиеся данные клиента в списке, идентифицируемом по гуиду, /// который у клиента в течение работы остается постоянным /// </summary> /// <param name="state">Объект-подключение</param> /// <param name="clientGuid">Идентификатор страницы</param> /// <param name="firstConnect">В первый ли раз подключается клиент</param> public static void UpdateClient(CometAsyncState state, string clientGuid, bool firstConnect = false) { WriteLog( $"Start UpdateClient CometAsyncState: {state.ClientGuid} clientGuid: {clientGuid} firstConnect: {firstConnect}"); var existState = false; lock (SyncLock) { // ищем клиента в списке по его гуиду var clientState = Connections.FirstOrDefault(s => s.ClientGuid == clientGuid); if (clientState != null) { // и если он нашелся, то обновляем все его параметры if (clientState.Start != DateTime.MinValue) { clientState.Start = DateTime.Now; } clientState.IsCompleted = false; clientState.Id = state.Id; clientState.Name = state.Name; clientState.IsEditable = state.IsEditable; //clientState.IsModified = state.IsModified; clientState.CurrentContext = state.CurrentContext; clientState.ExtraData = state.ExtraData; clientState.AsyncCallback = state.AsyncCallback; existState = true; } } if (!existState) { if (state != null) { state.ClientGuid = clientGuid; RegisterClient(state, false); WriteLog($"-> LOST CONNECTION UnregisterClient by state -> ClientGuid: {clientGuid}"); UnregisterClient(state, true); } else { throw new Exception("Отсутствует объект state! Ошибка организации вызова клиента!"); } } WriteLog("End UpdateClient"); }