/// <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); }
/// <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); }
/// <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); }
/// <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(); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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()); }
/// <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); }
/// <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; } } } } }