// Регистрация клиента
        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();
        }
Example #3
0
        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");
        }