コード例 #1
0
        /// <summary>
        /// Kill an IdleCometClient
        /// </summary>
        /// <param name="clientPrivateToken"></param>
        public void KillIdleCometClient(string clientPrivateToken)
        {
            //  get the comet client
            CometClient cometClient = this.StateProvider.GetCometClient(clientPrivateToken);

            //  ok, tmie the client out
            this.StateProvider.KillIdleCometClient(clientPrivateToken);
            //  and fire
            this.FireIdleClientKilled(cometClient);
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="callback"></param>
        /// <param name="extraData"></param>
        /// <returns></returns>
        public IAsyncResult BeginSubscribe(HttpContext context, AsyncCallback callback, object extraData)
        {
            try
            {
                long   lastMessageId;
                string privateToken = string.Empty;

                if (!long.TryParse(context.Request["lastMessageId"] ?? "-1", out lastMessageId))
                {
                    throw CometException.CometHandlerParametersAreInvalidException();
                }

                privateToken = context.Request["privateToken"];
                if (string.IsNullOrEmpty(privateToken))
                {
                    throw CometException.CometHandlerParametersAreInvalidException();
                }


                this.DebugWriteThreadInfo("BeginSubscribe");

                lock (state)
                {
                    Debug.WriteLine("目前有几个客户端连接" + this.GetCometClients());

                    CometClient cometClient = this.GetCometClient(privateToken);
                    this.FireClientSubscribed(cometClient);
                    // 从所有线程的请求队列中找到该CometClient,将其排除
                    for (int i = 0; i < this.workerThreadCount; i++)
                    {
                        this.workerThreads[i].DequeueCometWaitRequest(privateToken);
                    }

                    CometWaitRequest request = new CometWaitRequest(privateToken, lastMessageId, context, callback, extraData);

                    this.workerThreads[this.currentThread].QueueCometWaitRequest(request);
                    this.currentThread++;

                    if (this.currentThread >= this.workerThreadCount)
                    {
                        this.currentThread = 0;
                    }

                    return(request.Result);
                }
            }
            catch (Exception ex)
            {
                this.WriteErrorToResponse(context, ex.Message);
                return(null);
            }
        }
コード例 #3
0
 private void CheckForIdleCometWaitRequest(CometWaitRequest request, CometClient cometClient)
 {
     lock (state)
     {
         if (DateTime.Now.Subtract(request.DateDeactivated.Value).TotalSeconds >= cometClient.ConnectionIdleSeconds)
         {
             //  ok, this dude has timed out, so we remove it
             StateManager.KillIdleCometClient(cometClient.PrivateToken);
             //  and deque the request
             WaitRequests.Remove(request);
         }
     }
 }
コード例 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="publicToken">Comet客户端公开给外部的token,可以是用户名</param>
        /// <param name="privateToken">Comet客户端私有Token</param>
        /// <param name="aliasName">客户端别名</param>
        /// <param name="connectionTimeoutSeconds">客户端</param>
        /// <param name="connectionIdleSeconds"></param>
        /// <returns></returns>
        public void InitializeClient(string publicToken, string privateToken, string aliasName, int connectionTimeoutSeconds, int connectionIdleSeconds)
        {
            if (string.IsNullOrEmpty(publicToken))
            {
                throw new ArgumentNullException(nameof(publicToken));
            }
            if (string.IsNullOrEmpty(privateToken))
            {
                throw new ArgumentNullException(nameof(privateToken));
            }
            if (string.IsNullOrEmpty(aliasName))
            {
                throw new ArgumentNullException(nameof(aliasName));
            }
            if (connectionIdleSeconds <= 0)
            {
                throw new ArgumentOutOfRangeException("connectionIdleSeconds must be greater than 0");
            }
            if (connectionTimeoutSeconds <= 0)
            {
                throw new ArgumentOutOfRangeException("connectionTimeoutSeconds must be greater than 0");
            }

            var cometClient = new CometClient()
            {
                PublicToken              = publicToken,
                PrivateToken             = privateToken,
                AliasName                = aliasName,
                LastActivity             = DateTime.Now,
                ConnectionIdleSeconds    = connectionIdleSeconds,
                ConnectionTimeoutSeconds = connectionTimeoutSeconds,
            };

            try
            {
                StateProvider.InitializeClient(cometClient);
            }
            catch (Exception ex)
            {
                return;
            }
            FireClientInitialized(cometClient);
        }
コード例 #5
0
        public void InitializeClient(CometClient cometClient)
        {
            if (cometClient == null)
            {
                throw new ArgumentNullException(nameof(cometClient));
            }

            lock (state)
            {
                if (publicClients.ContainsKey(cometClient.PublicToken) || privateClients.ContainsKey(cometClient.PrivateToken))
                {
                    throw CometException.CometClientAlreadyExistsException();
                }

                var inProcCometClient = new InProcCometClient()
                {
                    CometClient = cometClient
                };
                publicClients.Add(cometClient.PublicToken, inProcCometClient);
                privateClients.Add(cometClient.PrivateToken, inProcCometClient);
            }
        }
コード例 #6
0
 internal void FireClientSubscribed(CometClient cometClient)
 {
     ClientSubscribed?.Invoke(this, new CometClientEventArgs(cometClient));
 }
コード例 #7
0
 internal void FireIdleClientKilled(CometClient cometClient)
 {
     IdleClientKilled?.Invoke(this, new CometClientEventArgs(cometClient));
 }
コード例 #8
0
 internal void FireClientInitialized(CometClient cometClient)
 {
     ClientInitialized?.Invoke(this, new CometClientEventArgs(cometClient));
 }
コード例 #9
0
        // 线程核心执行函数
        private void QueueCometWaitRequest_WaitCallback()
        {
            while (true)
            {
                CometWaitRequest[] processRequest;

                lock (state)
                {
                    processRequest = WaitRequests.ToArray();
                }
                //if (processRequest.Length == 0)
                //    break;

                if (processRequest.Length == 0)
                {
                    Thread.Sleep(100);
                }
                else
                {
                    for (int i = 0; i < processRequest.Length; i++)
                    {
                        try
                        {
                            CometClient cometClient = StateManager.StateProvider.GetCometClient(processRequest[i].ClientPrivateToken);

                            if (processRequest[i].Active)
                            {
                                Thread.Sleep(100);

                                if (DateTime.Now.Subtract(processRequest[i].DateTimeAdded).TotalSeconds >= cometClient.ConnectionTimeoutSeconds)
                                {
                                    DeactivateCometWaitRequest(processRequest[i]);
                                    CometMessage timeoutMessage = new CometMessage()
                                    {
                                        MessageId = 0,
                                        Tip       = "aspNetComet.timeout",
                                        Content   = null
                                    };
                                    processRequest[i].Result.CometMessages = new CometMessage[] { timeoutMessage };
                                    this.QueueCometWaitRequest_Finished(processRequest[i]);
                                }
                                else
                                {
                                    // 这里是消息响应的根本,响应给客户端的是 消息数组
                                    CometMessage[] messages = CheckForServerPushMessages(processRequest[i]);

                                    if (messages != null && messages.Length > 0)
                                    {
                                        processRequest[i].Result.CometMessages = messages;
                                        DeactivateCometWaitRequest(processRequest[i]);
                                        QueueCometWaitRequest_Finished(processRequest[i]);
                                    }
                                }
                            }
                            else
                            {
                                // 长连接 连接超时,断网或者 离线
                                this.CheckForIdleCometWaitRequest(processRequest[i], cometClient);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (processRequest[i].Active)
                            {
                                //  ok, this one has screwed up, so
                                //  we need to dequeue the request from ASP.NET, basically disable it and return
                                //  dequeue the request
                                DeactivateCometWaitRequest(processRequest[i]);

                                //  get the message
                                CometMessage errorMessage = new CometMessage()
                                {
                                    MessageId = 0,
                                    Tip       = "aspNetComet.error",
                                    Content   = ex.Message
                                };

                                //
                                //  ok, we we timeout the message
                                processRequest[i].Result.CometMessages = new CometMessage[] { errorMessage };
                                //  call the message
                                QueueCometWaitRequest_Finished(processRequest[i]);
                            }
                            else
                            {
                                //  this is not an active request, so we dequeue it from the
                                //  thread
                                DequeueCometWaitRequest(processRequest[i].ClientPrivateToken);
                            }
                        }
                    }
                }
            }
        }
コード例 #10
0
 public CometClientEventArgs(CometClient cometClient)
 {
     CometClient = cometClient;
 }