/// <summary> /// new command /// </summary> /// <param name="parameterLength"></param> /// <param name="socket"></param> private void NewCommand(Socket socket, byte parameterLength) { //Stopwatch stopwatch = null; int commandStart = 0; if (this.logMessage.Enable) { commandStart = Environment.TickCount; //stopwatch = Stopwatch.StartNew(); } //exec var serverName = (string)CsSocket.Receive(socket, STRING_TYPE); var commandName = (string)CsSocket.Receive(socket, STRING_TYPE); //invloke try { this.NewCommandInvoke(socket, parameterLength, serverName, commandName, commandStart); } catch (Exception exception) { throw new CsInvokeException(serverName, commandName, exception); } }
/// <summary> /// 方法调用 /// </summary> /// <param name="server"></param> /// <param name="command"></param> /// <param name="parameters"></param> /// <returns></returns> internal T Invoke <T>(string server, string command, params object[] parameters) { //仅最大支持255参数, max allow 255 parameter var parameterLength = (byte)parameters.Length; var value = default(T); //send using (var m = new MemoryStream()) { //length m.WriteByte(parameterLength); //namespace CsSocket.WriteDataItem(m, server); //name CsSocket.WriteDataItem(m, command); //parameters if (parameterLength > 0) { foreach (var param in parameters) { CsSocket.WriteDataItem(m, param); } } this.socket.Send(m.GetBuffer(), 0, (int)m.Length, SocketFlags.None); } this.invokeCount++; // var result = (CsResult)(SocketHelper.Receive(this.socket, 1)[0]); if (result == CsResult.Success) { //buffer parameter length , parameter index + parameter length + parameter body + bodylength + body var outputParameterLength = (SocketHelper.Receive(this.socket, 1)[0]); if (outputParameterLength > 0) { byte parameterIndex = 0; for (byte i = 0; i < outputParameterLength; i++) { parameterIndex = (SocketHelper.Receive(this.socket, 1)[0]); if (parameters[parameterIndex] == null) { throw new ArgumentNullException("out/ref parameter not allow is null"); } //read parameter parameters[parameterIndex] = CsSocket.Receive(socket, parameters[parameterIndex].GetType()); } } //read body value = (T)CsSocket.Receive(this.socket, typeof(T)); } else { var failureMessage = (string)CsSocket.Receive(this.socket, typeof(string)); throw new CsException(server, command, failureMessage); } // return(value); }
private void NewCommandInvoke(Socket socket, byte parameterLength, string serverName, string commandName, int commandStart) { object value = null; object[] parameters = null; var commandInfo = ServerCommand.GetCommand(serverName, commandName); if (commandInfo == null) { value = string.Format("Not Find Command:{0}.{1}", serverName, commandName); } else if (commandInfo.Parameters.Length != parameterLength) { value = string.Format("{0}.{1} Client Command Parameters And Server Parameters No Match", serverName, commandName); } else { //get parameter if (parameterLength > 0) { parameters = new object[parameterLength]; for (var i = 0; i < parameterLength; i++) { if (commandInfo.Parameters[i].IsOut) { CsSocket.Receive(socket); } else { parameters[i] = CsSocket.Receive(socket, commandInfo.Parameters[i].ParameterType); } } } } //cache byte[] cacheBuffer = null; String cacheVersion = null, cacheKey = null; var cacheType = ServerCacheType.NoCache; ServerConfigItem configItem = null; bool cacheEnable = false; //no error & get cache if (value == null) { if (ServerCache.Enable) { configItem = ServerConfig.GetItem(commandInfo.Server, commandInfo.Name); cacheEnable = configItem != null && configItem.CacheExpires > 0; } //cache get if (cacheEnable) { //mode = version if (configItem.CacheVersion != null) { try { cacheVersion = ServerCache.Cache.Get(configItem.CacheVersion); if (cacheVersion != null && cacheVersion != "") { //get cache cacheKey = ServerCache.BuildKey(configItem.CacheKey, cacheVersion, parameters); //value = ServerCache.Cache.Get(cacheKey, commandInfo.Method.ReturnType); cacheBuffer = ServerCache.Cache.Get <byte[]>(cacheKey); cacheType = cacheBuffer != null ? ServerCacheType.Cached : ServerCacheType.NoCache; } else { //no version , set no cache cacheEnable = false; } } catch (Exception e) { this.logManager.Exception(e); } } else { //get cache cacheKey = ServerCache.BuildKey(configItem.CacheKey, null, parameters); try { //value = ServerCache.Cache.Get(cacheKey, commandInfo.Method.ReturnType); cacheBuffer = ServerCache.Cache.Get <byte[]>(cacheKey); cacheType = cacheBuffer != null ? ServerCacheType.Cached : ServerCacheType.NoCache; } catch (Exception e) { this.logManager.Exception(e); } } } } var result = false; //cached if (cacheType == ServerCacheType.Cached) { socket.Send(cacheBuffer); result = true; } //no error ,invoke else if (value == null) { //var invokeStart = DateTime.Now; try { value = commandInfo.Method.Invoke(commandInfo.Instance, parameters); result = true; } catch (TargetInvocationException exception) { result = false; this.logManager.Exception(exception.GetBaseException()); value = exception.GetBaseException().Message; } catch (Exception exception) { result = false; this.logManager.Exception(exception); value = exception.Message; } //invokeSeconds = DateTime.Now.Subtract(invokeStart).TotalSeconds; //build value Buffer if (result) { using (var m = new MemoryStream()) { //write result m.WriteByte((byte)CsResult.Success); //send out parameter length //buffer parameter length , parameter index + parameter length + parameter body + bodylength + body //parameter count writer m.WriteByte(commandInfo.OutsIndexLength); //parameter write if (commandInfo.OutsIndexLength > 0) { for (byte i = 0, l = commandInfo.OutsIndexLength; i < l; i++) { //write index m.WriteByte(commandInfo.OutsIndex[i]); //write parameter CsSocket.WriteDataItem(m, parameters[commandInfo.OutsIndex[i]]); } } //body CsSocket.WriteDataItem(m, value); //build value buffer completed //svae value buffer to cache //if (result == CsResult.Success && cacheType == CacheType.NoCache && hasContent && commandInfo.CacheExpires > 0) if (cacheEnable && cacheType == ServerCacheType.NoCache) { cacheBuffer = m.ToArray(); try { //set cache ServerCache.Cache.Set(cacheKey, cacheBuffer, configItem.CacheExpires); cacheType = ServerCacheType.NewCache; } catch (Exception e) { this.logManager.Exception(e); } } //delete cache if (ServerCache.Enable && cacheEnable && configItem.CacheDeletes != null) { this.DeleteCache(commandInfo, configItem, parameters); } //send value if (cacheType == ServerCacheType.NewCache) { socket.Send(cacheBuffer); } else { socket.Send(m.GetBuffer(), 0, (int)m.Length, SocketFlags.None); } } } } else { //parameter error result = false; //value = "parameter error"; } //send error if (result == false) { using (var m = new MemoryStream()) { m.WriteByte((byte)CsResult.Fail); //write failure message CsSocket.WriteDataItem(m, (string)value); // socket.Send(m.GetBuffer(), 0, (int)m.Length, SocketFlags.None); } } // if (this.logMessage.Enable) { //this.logMessage.WriteTimeLine("{0}: {1}.{2}:{3}, Cache:{4}, InvokeSeconds:{5},Seconds:{6}", // this.id, serverName, commandName, result ? "Success" : "Failure", cacheType, invokeSeconds, DateTime.Now.Subtract(start).TotalSeconds); //stopwatch.Stop(); //var elapsedMilliseconds = stopwatch.ElapsedMilliseconds; var elapsedMilliseconds = Environment.TickCount - commandStart; //this.logMessage.WriteTimeLine("{0}: {1}.{2}:{3}, Cache:{4}, Elapsed:{5}", // this.id, serverName, commandName, result ? "Success" : "Failure", cacheType, stopwatch.Elapsed.TotalSeconds); this.logMessage.WriteTimeLine("{0}\t{1}\t{2}.{3}\t{4}\t{5}", this.id , cacheType , serverName , commandName , elapsedMilliseconds , (result ? "OK" : (string)value)); } }