/// <summary> /// new session /// </summary> /// <param name="socket"></param> private void NewSession(Socket socket) { var headBuffer = SocketHelper.Receive(socket, 4); var clientInfoDataLength = BitConverter.ToInt32(headBuffer, 0); if (clientInfoDataLength >= 0 && clientInfoDataLength < 65535) { //旧有版本使用的BitConvert.GetBytes序列化因此 根据旧版本长度不可能超过1000字节的依据,使用 > [0,0,0,0] = 0 && < [255,255,0,0] = 65535 CsInfo clientInfo = null; //body using (var m = SocketHelper.Receive(socket, clientInfoDataLength, CsSocket.BODY_BUFFER_SIZE)) { try { clientInfo = CsSerializer.Deserialize(typeof(CsInfo), m) as CsInfo; } catch (Exception) { socket.Close(); return; } } // if (clientInfo != null) { var session = new ServerSession(socket, this.serverLogger, this, clientInfo); lock (this.sessionCountLock) { session.Disposed += this.SessionDisposedCallback; this.sessionCount++; } session.ReceiveCommand(); } } //client >= 1.4 else { var session = new ServerSession2(socket, this.logManager, headBuffer); // lock (this.sessionCountLock) { session.Disposed += this.Session2DisposedCallback; this.sessionCount++; } session.ReceiveCommand(); } }
/// <summary> /// 读取 /// </summary> /// <param name="socket"></param> /// <param name="type"></param> /// <param name="deserialize"></param> /// <returns></returns> private object Receive(System.Net.Sockets.Socket socket, Type type, bool deserialize) { //length var length = BitConverter.ToInt32(SocketHelper.Receive(socket, CsSocket.LENGTH_BUFFER_SIZE), 0); //body using (var m = SocketHelper.Receive(socket, length, CsSocket.BODY_BUFFER_SIZE)) { if (deserialize) { try { return(CsSerializer.Deserialize(type, m)); } catch (Exception exception) { this.serverLogger.SessionException(this, exception); return(ReceiveParameterError.ERROR); } } return(null); } }
/// <summary> /// invoke /// </summary> /// <param name="commandInfo"></param> /// <param name="parameters"></param> /// <param name="valueBuffer"></param> /// <param name="cacheType"></param> /// <returns></returns> private CsResult Invoke(CommandInfo commandInfo, object[] parameters, out byte[] valueBuffer, out ServerCacheType cacheType) { /* * this method ,try catch, safe cache error */ //variable init string cacheKey = null; string cacheVersion = null; object invokeValue = null; var result = CsResult.Fail; //bool hasContent = false; // ServerConfigItem configItem = null; bool isCache = false; if (ServerCache.Enable) { configItem = ServerConfig.GetItem(commandInfo.Server, commandInfo.Name); isCache = configItem != null && configItem.CacheExpires > 0; } //init out valueBuffer = null; cacheType = ServerCacheType.NoCache; //cache get if (isCache) { //mode = version if (configItem.CacheVersion != null) { cacheVersion = ServerCache.Cache.Get(configItem.CacheVersion); } //get cache cacheKey = ServerCache.BuildKey(configItem.CacheKey, cacheVersion, parameters); try { valueBuffer = ServerCache.Cache.Get <byte[]>(cacheKey); result = CsResult.Success; } catch (Exception e) { this.serverLogger.CommandCacheException(commandInfo.Server, commandInfo.Name, e); } cacheType = valueBuffer != null && result == CsResult.Success ? ServerCacheType.Cached : ServerCacheType.NoCache; } //invoke if (valueBuffer == null) { cacheType = ServerCacheType.NoCache; result = CsResult.Success; //no ObjectCache if (invokeValue == null) { invokeValue = commandInfo.Method.Invoke(commandInfo.Instance, parameters); } //是否有内容 //hasContent = invokeValue != null; //buffer = bodylength+body, parameter index + parameter length + parameter using (var m = new MemoryStream(CsSocket.BODY_BUFFER_SIZE)) { //body using (var m2 = new MemoryStream(CsSocket.BODY_BUFFER_SIZE)) { if (invokeValue == null) { //length m.Write(BitConverter.GetBytes((int)-1), 0, CsSocket.LENGTH_BUFFER_SIZE); } else { CsSerializer.Serialize(m2, invokeValue); //length m.Write(BitConverter.GetBytes((int)m2.Length), 0, CsSocket.LENGTH_BUFFER_SIZE); //body m2.WriteTo(m); } } //parameters // count m.Write(BitConverter.GetBytes((int)commandInfo.OutsIndexLength), 0, CsSocket.LENGTH_BUFFER_SIZE); using (var m2 = new MemoryStream(CsSocket.BODY_BUFFER_SIZE)) { for (int i = 0, index = 0; i < commandInfo.OutsIndexLength; i++) { m2.SetLength(0); m2.Position = 0; // index = (int)commandInfo.OutsIndex[i]; //index m.Write(BitConverter.GetBytes(index), 0, CsSocket.LENGTH_BUFFER_SIZE); // if (parameters[index] == null) { //length m.Write(BitConverter.GetBytes((int)-1), 0, CsSocket.LENGTH_BUFFER_SIZE); } else { CsSerializer.Serialize(m2, parameters[index]); //length m.Write(BitConverter.GetBytes((int)m2.Length), 0, CsSocket.LENGTH_BUFFER_SIZE); //body m2.WriteTo(m); } } } // valueBuffer = m.ToArray(); } } //cache set //if (result == CsResult.Success && cacheType == CacheType.NoCache && hasContent && commandInfo.CacheExpires > 0) if (isCache && result == CsResult.Success && cacheType == ServerCacheType.NoCache) { try { //set cache ServerCache.Cache.Set(cacheKey, valueBuffer, configItem.CacheExpires); cacheType = ServerCacheType.NewCache; } catch (Exception e) { this.serverLogger.CommandCacheException(commandInfo.Server, commandInfo.Name, e); } } //delete cache if (ServerCache.Enable && isCache && configItem.CacheDeletes != null) { this.DeleteCache(commandInfo, configItem, parameters); } return(result); }
/// <summary> /// new command /// </summary> /// <param name="parameterLength"></param> /// <param name="socket"></param> private void NewCommand(Socket socket, int parameterLength) { object value = null; byte[] valueBuffer = null; var serverName = string.Empty; var commandName = string.Empty; var result = CsResult.Fail; var begin = DateTime.MaxValue; var end = DateTime.MaxValue; double invokeSeconds = 0; var start = DateTime.Now; var cacheType = ServerCacheType.NoCache; //exec serverName = (string)this.Receive(socket, STRING_TYPE, true); commandName = (string)this.Receive(socket, STRING_TYPE, true); var commandInfo = ServerCommand.GetCommand(serverName, commandName); if (commandInfo == null) { value = string.Format("Not Find Command:{0}.{1}", serverName, commandName); } // throw new NotFindCommandException(nameSpace, commandName); else if (commandInfo.Parameters.Length != parameterLength) { value = string.Format("{0}.{1} Parameter Legnth <> Invoke Parameter Length", serverName, commandName); } //throw new ApplicationException(string.Format("{0}.{1} Parameter Legnth <> Invoke Parameter Length", nameSpace, commandName)); object[] parameters = null; //no error if (value == null) { //get parameter if (parameterLength > 0) { parameters = new object[parameterLength]; for (var i = 0; i < parameterLength; i++) { if (commandInfo.Parameters[i].IsOut) { this.Receive(socket, commandInfo.Parameters[i].ParameterType, false); } else { parameters[i] = this.Receive(socket, commandInfo.Parameters[i].ParameterType, true); if (ReceiveParameterError.ERROR.Equals(parameters[i])) { value = "Parameter Error"; } } } } // if (value != null) { //parameter error result = CsResult.Fail; } else { //commandStopwatch.Start(); var invokeStart = DateTime.Now; try { result = this.Invoke(commandInfo, parameters, out valueBuffer, out cacheType); } catch (TargetInvocationException exception) { result = CsResult.Fail; this.serverLogger.CommandException(serverName, commandName, exception); value = exception.GetBaseException().Message; } catch (Exception exception) { result = CsResult.Fail; this.serverLogger.CommandException(serverName, commandName, exception); value = exception.Message; } //commandStopwatch.Stop(); invokeSeconds = DateTime.Now.Subtract(invokeStart).TotalSeconds; } } else { //read parameters data if (parameterLength > 0) { for (var i = 0; i < parameterLength; i++) { //length var length = BitConverter.ToInt32(SocketHelper.Receive(socket, CsSocket.LENGTH_BUFFER_SIZE), 0); //body using (var m = SocketHelper.Receive(socket, length, CsSocket.BODY_BUFFER_SIZE)) { m.Close(); } } } } //send using (var stream = new MemoryStream(CsSocket.BODY_BUFFER_SIZE)) { //send length stream.Write(BitConverter.GetBytes((int)result), 0, CsSocket.LENGTH_BUFFER_SIZE); //send out parameter length if (result == CsResult.Success) { stream.Write(valueBuffer, 0, valueBuffer.Length); } else { //error output using (var m = new MemoryStream(CsSocket.BODY_BUFFER_SIZE)) { CsSerializer.Serialize(m, value); stream.Write(BitConverter.GetBytes((int)m.Length), 0, CsSocket.LENGTH_BUFFER_SIZE); m.WriteTo(stream); } } socket.Send(stream.GetBuffer(), 0, (int)stream.Length, SocketFlags.None); } this.serverLogger.Command(this, serverName, commandName, result == CsResult.Success, cacheType, invokeSeconds, DateTime.Now.Subtract(start).TotalSeconds); }