Example #1
0
        /// <summary>
        /// 释放所有命令
        /// </summary>
        /// <param name="head"></param>
        /// <param name="end"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        internal ClientCommand.CommandBase Free(ClientCommand.CommandBase head, ClientCommand.CommandBase end, int startIndex)
        {
            DisposeTimeout();
            bool isNext = false;

            freeEndIndexLock.EnterSleepFlag();
            try
            {
                foreach (CommandLink[] array in arrays)
                {
                    if (isNext)
                    {
                        if (array == null)
                        {
                            break;
                        }
                        for (startIndex = array.Length; startIndex != 0;)
                        {
                            ClientCommand.Command command = array[--startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }
                    }
                    else
                    {
                        isNext = true;
                        do
                        {
                            ClientCommand.Command command = array[startIndex].Command;
                            if (command != null)
                            {
                                array[startIndex].Command = null;
                                if (head == null)
                                {
                                    head = end = command;
                                }
                                else
                                {
                                    end.LinkNext = command;
                                    end          = command;
                                }
                            }
                        }while (++startIndex != array.Length);
                    }
                }
            }
            finally { freeEndIndexLock.ExitSleepFlag(); }
            return(head);
        }
Example #2
0
        /// <summary>
        /// 获取文件缓存,失败时创建缓存对象
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileCache"></param>
        /// <param name="isCopyPath">是否复制请求路径</param>
        /// <returns>是否新的文件缓存数据</returns>
        private byte get(ref FileCacheKey path, out FileCache fileCache, bool isCopyPath)
        {
            byte isNewFileCache = 0;

            fileLock.Enter();
            if ((fileCache = files.Get(ref path, null)) == null)
            {
                fileLock.SleepFlag = 1;
                byte isLock = 0;
                try
                {
                    fileCache = new FileCache();
                    isLock    = 1;
                    if (isCopyPath)
                    {
                        path.CopyPath();
                    }
                    files.UnsafeAdd(ref path, fileCache);
                    return(isNewFileCache = 1);
                }
                finally
                {
                    fileLock.ExitSleepFlag();
                    if (isNewFileCache == 0 && isLock != 0)
                    {
                        fileCache.PulseAll();
                    }
                }
            }
            else
            {
                fileLock.Exit();
            }
            return(0);
        }
Example #3
0
        /// <summary>
        /// 根据类型获取成员索引分组
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <returns>成员索引分组</returns>
        public static MemberIndexGroup Get(Type type)
        {
            MemberIndexGroup value;

            cacheLock.Enter();
            try
            {
                if (!cache.TryGetValue(type, out value))
                {
                    cacheLock.SleepFlag   = 1;
                    cache.Add(type, value = new MemberIndexGroup(type, false));
                }
            }
            finally { cacheLock.ExitSleepFlag(); }
            return(value);
        }
Example #4
0
        /// <summary>
        /// 输出错误状态
        /// </summary>
        /// <param name="state">错误状态</param>
        internal void ResponseError(ResponseState state)
        {
            if (DomainServer != null)
            {
                Response response = DomainServer.GetErrorResponseData(state, Header.IsGZip);
                if (response != null)
                {
                    if (state != ResponseState.NotFound404 || Header.Method != MethodType.GET)
                    {
                        Header.Flag &= HeaderFlag.All ^ HeaderFlag.IsKeepAlive;
                    }
                    if (responseHeader(ref response)) return;
                }
            }
            byte[] data = errorResponseDatas[(int)state];
            System.Net.Sockets.Socket socket = Socket;
            if (data != null && socket != null)
            {
                try
                {
                    SendType = state == ResponseState.NotFound404 && Header.Method == MethodType.GET ? SendType.Next : SendType.Close;
                    Data.Set(data, 0, data.Length);
                    Timeout = Config.GetTimeout(Data.Length);
#if DOTNET2
                    SocketError socketError;
                    IAsyncResult async = socket.BeginSend(data, 0, Data.Length, SocketFlags.None, out socketError, onSendAsyncCallback, socket);
                    if (socketError == SocketError.Success)
                    {
                        if (!async.CompletedSynchronously) Http.Header.ReceiveTimeout.Push(this, socket);
                        return;
                    }
#else
                    sendAsyncLock.EnterSleepFlag();
                    sendAsyncEventArgs.SetBuffer(data, 0, Data.Length);
                    if (socket.SendAsync(sendAsyncEventArgs))
                    {
                        sendAsyncLock.SleepFlag = 0;
                        Http.Header.ReceiveTimeout.Push(this, socket);
                        sendAsyncLock.Exit();
                        return;
                    }
                    sendAsyncLock.ExitSleepFlag();
                    if (onSend()) return;
#endif
                }
                catch (Exception error)
                {
                    Server.RegisterServer.TcpServer.Log.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer);
                }
            }
            HeaderError();
        }
Example #5
0
 /// <summary>
 /// 重建短路径
 /// </summary>
 /// <param name="client"></param>
 /// <returns></returns>
 private bool reCreate(MasterServer.TcpInternalClient client)
 {
     createLock.SleepFlag = 1;
     try
     {
         do
         {
             socketIdentity = Client.SocketIdentity;
             AutoCSer.Net.TcpServer.ReturnValue <ReturnParameter> value = client.Query(new OperationParameter.QueryNode {
                 Node = Parameter
             });
             if (socketIdentity == Client.SocketIdentity)
             {
                 return(isCreate(ref value));
             }
         }while (true);
     }
     catch (Exception error)
     {
         client._TcpClient_.AddLog(error);
     }
     finally { createLock.ExitSleepFlag(); }
     return(false);
 }
Example #6
0
        /// <summary>
        /// 获取服务端节点标识
        /// </summary>
        /// <param name="remoteTypes"></param>
        /// <returns></returns>
        internal unsafe static int[] Get(AutoCSer.Reflection.RemoteType[] remoteTypes)
        {
            int[] ids = new int[remoteTypes.Length];
            fixed(int *idFixed = ids)
            {
                int *idStart = idFixed;

                foreach (AutoCSer.Reflection.RemoteType remoteType in remoteTypes)
                {
                    Type type;
                    if (remoteType.TryGet(out type))
                    {
                        if (types.TryGetValue(type, out *idStart))
                        {
                            ++idStart;
                        }
                        else
                        {
                            typeLock.Enter();
                            if (types.TryGetValue(type, out *idStart))
                            {
                                typeLock.Exit();
                                ++idStart;
                            }
                            else
                            {
                                typeLock.SleepFlag = 1;
                                try
                                {
                                    Func <Node> createNode = (Func <Node>)Delegate.CreateDelegate(typeof(Func <Node>), createNodeMethod.MakeGenericMethod(type));
                                    int         id         = createNodes.Length;
                                    createNodes.Add(createNode);
                                    types.Add(type, id);
                                    *idStart++ = id;
                                }
                                finally { typeLock.ExitSleepFlag(); }
                            }
                        }
                    }
                    else
                    {
                        *idStart++ = 0;
                    }
                }
            }

            return(ids);
        }
Example #7
0
        internal static int RegisterClient(Func <ReturnValue> createReturnValue)
        {
            createReturnValueLock.Enter();
            int id = createReturnValues.Length;

            try
            {
                if (createReturnValues.FreeCount == 0)
                {
                    createReturnValueLock.SleepFlag = 1;
                }
                createReturnValues.Add(createReturnValue);
            }
            finally { createReturnValueLock.ExitSleepFlag(); }
            return(id);
        }
Example #8
0
 /// <summary>
 /// 获取域名服务信息
 /// </summary>
 /// <param name="domain">域名</param>
 /// <param name="size">域名长度</param>
 /// <returns>域名服务信息</returns>
 internal DomainServer Get(byte *domain, int size)
 {
     if (searcher.State != null)
     {
         if (lastDomainSize == size && lastLock.TryEnter())
         {
             if (lastDomainSize == size && AutoCSer.Memory.Common.SimpleEqualNotNull(lastDomain.Byte, domain, lastDomainSize))
             {
                 DomainServer server = lastServer;
                 lastLock.Exit();
                 return(server);
             }
             lastLock.Exit();
         }
         int index = searcher.Search(domain, domain + size);
         if (index >= 0)
         {
             DomainServer server = servers[index];
             if (server != null)
             {
                 if (lastLock.TryEnter())
                 {
                     if (lastDomain.Byte == null)
                     {
                         lastLock.SleepFlag = 1;
                         try
                         {
                             lastDomain = Unmanaged.GetPointer(Server.MaxDomainSize, false);
                             AutoCSer.Memory.Common.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size);
                             lastServer = server;
                         }
                         finally { lastLock.ExitSleepFlag(); }
                     }
                     else
                     {
                         AutoCSer.Memory.Common.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size);
                         lastServer = server;
                         lastLock.Exit();
                     }
                 }
                 return(server);
             }
         }
     }
     return(null);
 }
Example #9
0
        /// <summary>
        /// 添加用户长连接轮询验证
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        internal string Add(int userId)
        {
            AutoCSer.Net.HttpDomainServer.SessionId sessionId;
            int index = userId >> 8;

            sessionLock.Enter();
            if ((uint)index < (uint)sessions.Length)
            {
                sessionId = sessions[index].Get(timeoutTicks);
                sessionLock.Exit();
            }
            else
            {
                sessionLock.SleepFlag = 1;
                try
                {
                    sessions  = sessions.copyNew(Math.Max(sessions.Length << 1, index + 256));
                    sessionId = sessions[index].New(timeoutTicks);
                }
                finally { sessionLock.ExitSleepFlag(); }
            }
            return(sessionId.ToHex());
        }
Example #10
0
        /// <summary>
        /// 输出 HTTP 响应数据
        /// </summary>
        /// <param name="response">HTTP 响应数据</param>
        private void response(ref Response response)
        {
            bool isHeaderError = false;
            try
            {
                CheckNotChanged304(ref response);
                if (Header.Method == MethodType.POST && (Flag & SocketFlag.IsLoadForm) == 0)
                {
                    Header.IgnoreContentLength();
                    if (Header.ContentLength == 0)
                    {
                        isHeaderError = true;
                        if (responseHeader(ref response)) return;
                    }
                    else
                    {
                        System.Net.Sockets.Socket socket = Socket;
                        if (socket == null) Http.Response.Push(ref response);
                        else
                        {
                            this.HttpResponse = response;
                            ReceiveType = ReceiveType.Response;
                            Data.Set(Buffer.Buffer, Buffer.StartIndex, Math.Min(Header.ContentLength, Buffer.Length));
                            response = null;
                            Timeout = Config.GetTimeout(Header.ContentLength);
#if DOTNET2
                                SocketError socketError;
                                IAsyncResult async = socket.BeginReceive(Buffer.Buffer, Buffer.StartIndex, Data.Length, SocketFlags.None, out socketError, onReceiveAsyncCallback, socket);
                                if (socketError == SocketError.Success)
                                {
                                    if (!async.CompletedSynchronously) Http.Header.ReceiveTimeout.Push(this, socket);
                                    return;
                                }
#else
                            receiveAsyncEventArgs.SocketError = SocketError.Success;
                            ReceiveAsyncLock.EnterSleepFlag();
                            receiveAsyncEventArgs.SetBuffer(Buffer.Buffer, Buffer.StartIndex, Data.Length);
                            if (socket.ReceiveAsync(receiveAsyncEventArgs))
                            {
                                ReceiveAsyncLock.SleepFlag = 0;
                                Http.Header.ReceiveTimeout.Push(this, socket);
                                ReceiveAsyncLock.Exit();
                                return;
                            }
                            ReceiveAsyncLock.ExitSleepFlag();
                            isHeaderError = true;
                            if (onReceive()) return;
#endif
                        }
                    }
                }
                else
                {
                    isHeaderError = true;
                    if (responseHeader(ref response)) return;
                }
            }
            catch (Exception error)
            {
                Server.RegisterServer.TcpServer.Log.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer);
            }
            if (isHeaderError) HeaderError();
            else ResponseError(ResponseState.ServerError500);
        }
Example #11
0
        /// <summary>
        /// 接收数据回调处理
        /// </summary>
        /// <param name="data">输出数据</param>
        internal override void OnReceive(ref SubArray <byte> data)
        {
            Action <ReturnValue> callback = Callback;

            if (callback != null)
            {
                ReturnType value = GetReturnType(ref data);
                if ((byte)value < (byte)ReturnType.Success)
                {
                    KeepCallback.Cancel();
                }
                if (CommandInfo.TaskType == ClientTaskType.Synchronous)
                {
                    try
                    {
                        callback(new ReturnValue {
                            Type = value
                        });
                    }
                    catch (Exception error) { Socket.Log.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer); }
                }
                else
                {
                    int       isOutput  = 1;
                    Exception exception = null;
                    OutputLock.Enter();
                    try
                    {
                        if (outputParameters.FreeCount == 0)
                        {
                            OutputLock.SleepFlag = 1;
                        }
                        outputParameters.Add(value);
                        isOutput      = this.isOutput;
                        this.isOutput = 1;
                    }
                    catch (Exception error) { exception = error; }
                    finally
                    {
                        OutputLock.ExitSleepFlag();
                        if (exception != null)
                        {
                            Socket.Log.Exception(exception, null, LogLevel.Exception | LogLevel.AutoCSer);
                        }
                    }
                    if (isOutput == 0)
                    {
                        switch (CommandInfo.TaskType)
                        {
                        case ClientTaskType.ThreadPool: if (!System.Threading.ThreadPool.QueueUserWorkItem(threadPoolOnReceive))
                            {
                                AutoCSer.Threading.TaskSwitchThreadArray.Default.CurrentThread.Add(this);
                            }
                            return;

                        case ClientTaskType.Timeout: AutoCSer.Threading.TaskSwitchThreadArray.Default.CurrentThread.Add(this); return;

                        case ClientTaskType.TcpTask: ClientCallThreadArray.Default.CurrentThread.Add(this); return;

                        case ClientTaskType.TcpQueue: ClientCallQueue.Default.Add(this); return;
                        }
                    }
                }
            }
        }