예제 #1
0
파일: CSocket.cs 프로젝트: zz412000428/Gaea
 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);
 }
예제 #2
0
 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);
     }
 }
예제 #3
0
 /// <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)));
         }
     }
 }
예제 #4
0
 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;
     }
 }
예제 #5
0
파일: SocketPool.cs 프로젝트: GavinHwa/Gaea
        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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
파일: Server.cs 프로젝트: zz412000428/Gaea
        /// <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();
            }
        }