public int Send(byte[] data) { ThreadPool.QueueUserWorkItem(delegate(object param) { byte[] sendData = new byte[data.Length + CONST.P_START_TAG.Length + CONST.P_END_TAG.Length]; Array.Copy(CONST.P_START_TAG, 0, sendData, 0, CONST.P_START_TAG.Length); Array.Copy(data, 0, sendData, CONST.P_START_TAG.Length, data.Length); Array.Copy(CONST.P_END_TAG, 0, sendData, CONST.P_START_TAG.Length + data.Length, CONST.P_END_TAG.Length); SocketError error; int sendcount = socket.Send(sendData, 0, sendData.Length, SocketFlags.None, out error); if (sendcount > 0 && error == SocketError.Success) { return; } else if (sendcount <= 0) { logger.Error(String.Format("Failed to write to the socket '{0}'. Error: {1}", endpoint, error)); throw new IOException(String.Format("Failed to write to the socket '{0}'. Error: {1}", endpoint, error)); } else if (error == SocketError.TimedOut) { logger.Warn("socket send timeout! host:" + endpoint.Address); throw new SendTimeoutException(); } else { logger.Error("socket exception,error:" + error.ToString() + " Code:" + (int)error + ",host:" + endpoint.Address); throw new OtherException("socket exception,error:" + error.ToString() + " Code:" + (int)error); } }); return(data.Length); }
private void responseExceptionHandler(HttpRequest req, Exception exception, HttpResponse resp) { lock (_log) { if (req != null && resp != null) { _log.Error("Error in response for request {0}, status code {1}:".Fmt(req.Url.ToFull(), (int)resp.Status)); } PropellerUtil.LogException(_log, exception); } }
/// <summary> /// Logs an exception.</summary> /// <param name="log"> /// Logger to log the exception to.</param> /// <param name="e"> /// The exception to log.</param> public static void LogException(LoggerBase log, Exception e) { lock (log) { log.Error(@"Exception: {0} ({1})".Fmt(e.Message, e.GetType().FullName)); log.Error(e.StackTrace); var indent = 0; while (e.InnerException != null) { indent += 4; e = e.InnerException; log.Error(" -- Inner exception: {0} ({1})".Fmt(e.Message, e.GetType().FullName).Indent(indent)); log.Error(e.StackTrace.NullOr(st => st.Indent(indent))); } } }
public override byte[] Serialize(object obj) { try { using (MemoryStream ms = new MemoryStream()) { DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType()); ser.WriteObject(ms, obj); byte[] json = ms.ToArray(); return(json); } } catch (Exception ex) { logger.Error("JsonSerialize Serialize Error! " + ex.Message); throw ex; } }
public CSocket GetScoket() { CSocket rSocket = null; lock (pool) { if (pool.Count > 0) { rSocket = pool.Dequeue(); } else if (pool.Total < socketPoolConfig.MaxPoolSize) { var socket = new CSocket(endPoint, this, socketPoolConfig); pool.AllSocket.Add(socket); rSocket = socket; logger.Info("created new socket.server:" + _Server.Name); } else { if (!releasedEvent.WaitOne((int)socketPoolConfig.WaitTimeout.TotalMilliseconds)) { logger.Error("socket connection pool is full(" + pool.Total + ")!server cu:" + _Server.CurrUserCount); throw new TimeoutException("socket connection pool is full!"); } else { rSocket = pool.Dequeue(); } } } if (rSocket == null) { throw new Exception("can't get socket from pool!"); } rSocket.Reset(); rSocket.InPool = false; return(rSocket); }
/// <summary> /// Loads Propeller settings from the appropriate location. Using this method ensures that settings are loaded in /// exactly the same way and from the same place as the Propeller engine would load them.</summary> /// <param name="settingsPath"> /// Path and filename of the settings to load.</param> /// <param name="log"> /// Information about how the settings were loaded is logged here. Must not be <c>null</c>.</param> /// <param name="firstRunEver"> /// Adjusts the log messages for improved human readability.</param> public static PropellerSettings LoadSettings(string settingsPath, LoggerBase log, bool firstRunEver) { settingsPath = settingsPath ?? SettingsUtil.GetAttribute <PropellerSettings>().GetFileName(); log.Info((firstRunEver ? "Loading settings file: " : "Reloading settings file: ") + settingsPath); PropellerSettings settings; var success = false; try { success = SettingsUtil.LoadSettings(out settings, settingsPath); if (success) { settings.SaveQuiet(settingsPath); return(settings); } } catch (Exception e) { settings = new PropellerSettings(); log.Error("Settings file could not be loaded: {0} ({1}). Using default settings.".Fmt(e.Message, e.GetType().FullName)); } if (!success) { if (!File.Exists(settingsPath)) { try { settings.Save(settingsPath); log.Info("Default settings saved to {0}.".Fmt(settingsPath)); } catch (Exception ex) { log.Warn("Attempt to save default settings to {0} failed: {1} ({2})".Fmt(settingsPath, ex.Message, ex.GetType().FullName)); } } } return(settings); }
private bool reinitialize() { // If we are already initialized and the settings file hasn’t changed, we don’t need to do anything. var firstRunEver = _server == null; if (_server != null && File.GetLastWriteTimeUtc(_settingsPath) <= _settingsLastChangedTime) { return(false); } // This may load *and re-write* the settings file... var newSettings = PropellerUtil.LoadSettings(_settingsPath, firstRunEver ? new ConsoleLogger() : _log, firstRunEver); // ... so remember the file date/time stamp *after* the writing _settingsLastChangedTime = File.GetLastWriteTimeUtc(_settingsPath); _log = PropellerUtil.GetLogger(true, newSettings.LogFile, newSettings.LogVerbosity); _log.Info(firstRunEver ? "Initializing Propeller" : "Reinitializing Propeller"); // If either port number or the bind-to address have changed, stop and restart the server’s listener. var startListening = false; if (_server == null || CurrentSettings == null || !CurrentSettings.ServerOptions.Endpoints.Values.SequenceEqual(newSettings.ServerOptions.Endpoints.Values)) { var removed = CurrentSettings == null ? new HttpEndpoint[0] : CurrentSettings.ServerOptions.Endpoints.Values.Except(newSettings.ServerOptions.Endpoints.Values).ToArray(); var added = CurrentSettings == null?newSettings.ServerOptions.Endpoints.Values.ToArray() : newSettings.ServerOptions.Endpoints.Values.Except(CurrentSettings.ServerOptions.Endpoints.Values).ToArray(); if (_server == null || removed.Length > 0 || added.Length > 0) { if (removed.Length > 0) { _log.Info("Disabling {0}".Fmt(removed.Select(ep => "HTTP{0} on port {1}".Fmt(ep.Secure ? "S" : null, ep.Port)).JoinString(", ", lastSeparator: " and "))); } if (added.Length > 0) { _log.Info("Enabling {0}".Fmt(added.Select(ep => "HTTP{0} on port {1}".Fmt(ep.Secure ? "S" : null, ep.Port)).JoinString(", ", lastSeparator: " and "))); } if (_server == null) { _server = new HttpServer { Options = newSettings.ServerOptions, ErrorHandler = errorHandler, ResponseExceptionHandler = responseExceptionHandler } } ; else { _server.StopListening(); } startListening = true; } } CurrentSettings = newSettings; // Create a new instance of all the modules var newAppDomains = new HashSet <AppDomainInfo>(); foreach (var module in newSettings.Modules) { _log.Info("Initializing module: " + module.ModuleName); try { var inf = new AppDomainInfo(_log, newSettings, module, new SettingsSaver(s => { module.Settings = s; _settingsSavedByModule = true; })); newAppDomains.Add(inf); } catch (Exception e) { _log.Error("Failed to initialize module {0}:".Fmt(module.ModuleName)); _log.Exception(e); } } // Switcheroo! lock (_lockObject) { _log.Info("AppDomain Switcheroo"); _inactiveAppDomains.AddRange(_activeAppDomains); _activeAppDomains = newAppDomains; _server.Options = newSettings.ServerOptions; _server.Handler = createResolver().Handle; _server.Log = PropellerUtil.GetLogger(newSettings.HttpAccessLogToConsole, newSettings.HttpAccessLogFile, newSettings.HttpAccessLogVerbosity); if (startListening) { _server.StartListening(); } } // Delete any remaining temp folders no longer in use HashSet <string> tempFoldersInUse; lock (_lockObject) tempFoldersInUse = _activeAppDomains.Concat(_inactiveAppDomains).Select(ad => ad.TempPathUsed).ToHashSet(); foreach (var tempFolder in Directory.EnumerateDirectories(CurrentSettings.TempFolder ?? Path.GetTempPath(), "propeller-tmp-*")) { if (tempFoldersInUse.Contains(tempFolder)) { continue; } try { Directory.Delete(tempFolder, recursive: true); } catch { } } return(true); }
public InvokeResult Invoke(Type returnType, string typeName, string methodName, params Parameter[] paras) { logger.Debug("current thread count:" + ThreadCount); if (ThreadCount > config.MaxThreadCount) { logger.Error("server is too busy(" + ThreadCount + ").Service:" + _ServiceName); throw new Exception("server is too busy.(" + _ServiceName + ")"); } try { System.Threading.Interlocked.Increment(ref ThreadCount); Stopwatch watcher = new Stopwatch(); watcher.Start(); List <RpParameter> listPara = new List <RpParameter>(); IList <Type> outParaTypes = new List <Type>(); Array.ForEach(paras, delegate(Parameter p) { listPara.Add(new RpParameter(TypeMapping.ParseType(p.DataType.ToString()), p.Para)); if (p.ParaType == Com.Bj58.Spat.Gaea.Client.Proxy.Enum.ParaType.Out) { outParaTypes.Add(p.DataType); } }); RequestProtocol requestProtocol = new RequestProtocol(typeName, methodName, listPara.ToArray()); byte[] userData = config.Protocol.Serializer.Serialize(requestProtocol); Protocol sendP = new Protocol(config.Protocol, CreateSessionId(), UserDataType.Request, userData); var server = dispatcher.GetServer(); if (server == null) { logger.Error("can't get server"); throw new Exception("can't get server"); } Protocol receiveP = server.Request(sendP);//request server if (receiveP.UserDataType == UserDataType.Response) { var rpGtype = returnType; if (returnType == typeof(void)) { rpGtype = typeof(VOID); } var rpType = typeof(ResponseProtocol <>).MakeGenericType(rpGtype); var rp = config.Protocol.Serializer.Deserialize(receiveP.UserData, rpType); object result = rpType.GetProperty("Result").GetValue(rp, null); object[] outPara = (object[])rpType.GetProperty("Outpara").GetValue(rp, null); logger.Debug("invoke time:" + watcher.ElapsedMilliseconds + "ms"); return(new InvokeResult(result, outPara)); } else if (receiveP.UserDataType == UserDataType.Exception) { var ep = config.Protocol.Serializer.Deserialize <ExceptionProtocol>(receiveP.UserData); throw ExceptionProvider.ThrowServiceError(ep.ErrorCode, ep.ErrorMsg); } else { logger.Error("userdatatype error!"); throw new Exception("userdatatype error!"); } } finally { System.Threading.Interlocked.Decrement(ref ThreadCount); } }
/// <summary> /// send a protocol data to server and get a result /// </summary> /// <param name="p">protocol data(SFP)</param> /// <returns>result data(SFP Data)</returns> public virtual Protocol Request(Protocol p) { Stopwatch watcher = new Stopwatch(); StringBuilder log = new StringBuilder(); IncreaseCU(); if (State != ServerState.Normal && State != ServerState.Testing) { logger.Warn("this server too busy.state:" + State + "+host:" + Address); throw new Exception("this server too busy.state:" + State + "+host:" + Address); } CSocket socket = null; try { byte[] data = p.ToBytes(); using (socket = this.ScoketPool.GetScoket()) { socket.Send(data); } byte[] buffer = socket.Receive(p.SessionID); Protocol result = new Protocol(buffer); if (this.State == ServerState.Testing) { Relive(); } ErrorCount = 0; return(result); } catch (SocketException err) { logger.Error("Occur socket exception.server:" + this.Address + ":" + this.Port + ".message:" + err.Message); if (State == ServerState.Testing) { MarkAsDead(); } else if (!Test()) { MarkAsDead(); } throw; } catch (System.IO.IOException err) { logger.Error("Occur IO exception.server:" + this.Address + ":" + this.Port + ".message:" + err.Message); if (State == ServerState.Testing) { MarkAsDead(); } else if (!Test()) { MarkAsDead(); } throw; } catch { if (State == ServerState.Testing) { MarkAsDead(); } throw; } finally { DecreaseCU(); } }