• 基于.Net Remoting的应用程序


    本文对《AppLogger, a Simple Distributed Application Logger - Part 1, By sebma, http://www.codeproject.com/csharp/MaAppLogger.asp#xx870711xx》一文进行了分析,并在此基础上进行功能扩展(DBLogger & EmailLogger),同时将Remote Object移植到IIS环境。如果将Remote Object移植到IIS环境中,需要修改FileLogger,另外还会出现许多相关的问题。下面针对这些问题的原因及其解决办法分别进行介绍。

    一般而言,在实际的应用系统中,由IIS承载Remote Object比较容易维护和管理,并且也比较稳定。关于如何将Remote Object部署在IIS下,可以参考《如何在IIS中承载远程对象》一文。

    经过修改后的Application Logger based on .Net Remoting总体架构如下:

     

    Client & Server Side共享AppRemotingLogger::BusinessFacade。Client只需要引用AppRemoting.BusinessFacade.dll,任何在BusinessRules和DataAccess层的修改对Client端没有影响。Server端可以根据需要修改Logger的类型。

    注:AppRemotingLoggerHelp Class移到到Implementation/Client层,AppRemotingLoggerHelp实现对Remote Object的调用,并封装对各种类型Message的log操作,如Exception, Error, Warning, Info and Debug(Debug Message只有在调试阶段才记录日志)。

    1. 主要类库分析

    (1)BusinessRules Layer的Logger

     

    FileLoger – 记录日志文件(text file)到指定的目录,每个Application有对应的日志文件。

    EventLoger – 日志输出到Server端Event Viewer,个人觉得不是很实用。

    DebugLogger - 记录日志输出到DebugView(最后的参考文档处提供有下载URL),如果Remote Object部署在IIS环境下,则失效。

    ConsoleLogger – 如果Remote Object部署在IIS环境下,则失效。如果Remote Object由EXE承载,ConsoleLogger比较方便调试。

    下面2个logger是我自己加进去的,代码比较简单,就不贴出来了。

    EmailLogger – 以邮件的方式输出日志到指定的receiver。

    DBLogger – 将日志记录到指定数据库的数据表中,个人觉得这个logger比较实用。

    DefaultAppRemotingLogger – 实现IappLogger接口,调用LoggerFactory,并根据Web.config文件的设置生成Logger实体。

     

    DefaultHome Class实现Ihome接口,并且是Client可以访问的Remote Object。从如下Web.config文件中可以看到:

    <wellknown

    mode="SingleCall"

    type="AppRemotingLogger.BusinessRules.DefaultHome, AppRemotingLogger.BusinessRules"

    objectUri="AppRemotingLogger.IHome.soap" />

    DefaultHome Class中GetAppLogger()方法调用DefaultAppRemotingLogger,返回Logger实例。

    DefaultAppRemotingLogger Class调用LoggerFactory,并根据Web.config中

    <add key="AppRemotingLogger.Type" value="AppRemotingLogger.BusinessRules.FileLogger" />

    的设定,生成Logger对象。

    另外,DefaultAppRemotingLogger Class中LogMessage()方法通过使用线程池来实现异步记录日志,避免造成系统瓶颈。

    2. 如何调试部署在IIS中的Remote Object

    为了调试部署在IIS中的Remote Object,需要将aspnet_wp进程附加进来(attach),这个在开发测试过程中非常重要。具体过程如下:

    (1)在client端设置断点,并进入调试状态。

    (2)点击”Tools/Debug Processes…”,附加aspnet_wp进程。如下图所示:

    注意,其中Name根据IIS服务运行的机器,选择/输入相应的computer name。

     

    3. 需要注意的若干问题

    DBLogger & EmailLogger的coding比较简单,这里省略了。不过在调试过程中,需要注意如下一些问题。

    (I)EmailLogger可能存在“Could not access ‘CDO.Message’ object”异常

    导致的原因及其解决办法:

    (1)SmtpServer等参数设置有问题,确保参数设置正确。

    (2)因为Web.Mail需要调用CDOSYS.dll,有可能CDOSYS.dll没有注册好,可通过regsvr32 /u 先取消注册,然后在用regsvr32在注册一次。

    (3)如问题仍没有解决,可以尝试修改

    C:\WINNT\Microsoft.NET\Framework\v1.1.4322\CONFIG目录下的machine.config文件,并将<processModel> Section中的UserName属性设置为SYSTEM。

    其实,我使用默认的UserName=machine也可以成功的发送email。

    (II)EventLogger可能存在“Requested registry access is not allowed”异常

    导致的原因及其解决办法:

    ASP.Net账号没有足够的权限写Event List,只要将machine.config中的UserName属性设置为SYSTEM就可以解决了。不过,EventLogger其实不是很实用。

    (III)FileLogger可能存在“Access to the path c:\winnt\system32\<filename> is denied”异常

    导致的原因及其解决办法:

    FileLogger默认将日志记录在c:\winnt\system32\目录,ASP.NET帐户根本就没有对该目录的访问权限。因此,需要修改DataAccess项目中的LogFileDataWriter.cs文件。

    public LogFile(string strFileName)

    {

           string strFileLoggerPath = ConfigurationSettings.AppSettings["FileLoggerPath"];

           if(strFileLoggerPath == null || strFileLoggerPath.Trim().Length == 0)

           {

                       strFileLoggerPath = @"c:\Inetpub\wwwroot";

           }

           strFileName = @strFileLoggerPath + strFileName;

           m_objFileStream = new FileStream(strFileName,

                       FileMode.Append,

                       FileAccess.Write,

                       FileShare.Read);

    }

    明确指定日志文件存放的路径"FileLoggerPath"(在web.config文件<appSettings>中设定),同时需要给予ASP.NET帐户对该目录的Full Control权限。

    (IV)DebugLogger在IIS环境中失效,不过没有Exception抛出

    的确如此,这个问题没有找到解决办法。不过关系不大,不使用DebugLogger就可以了。

    DebugView可以从http://www.sysinternals.com/ntw2k/freeware/debugview.shtml下载。

    我在测试EXE承载的Remote Object时,DebugView可以捕获到Trace消息,一切运行正常。但当Remote Object部署在IIS中后,DebugView就无法捕获到Trace消息了。

    通过断点测试,Trace.WriteLine(objBuilder.ToString())语句是正确执行的,没有抛出异常。

    (V)The remote server returned an error: (407) Proxy Authentication Required异常.

    导致的原因及其解决办法:

    一般而言是由于IE中设置采用Proxy,如果Disable IE proxy settings,应该就没有问题了。先测试一下,如果可行,则通过如下的code告诉HttpChannel不要访问Proxy Server Settings,来彻底上述解决。

    HttpChannel theChannel = (HttpChannel)ChannelServices.GetChannel("http");

    theChannel.Properties["proxyName"] = null;

    将上面的2行代码放在获取Remote Object的代码后面。

    我采用Activator.GetObject()方法来获取Remote Object,上述代码会出现Cast错误。对上述代码稍做修改如下:

    System.Runtime.Remoting.Channels.Http.HttpClientChannel theChannel = (System.Runtime.Remoting.Channels.Http.HttpClientChannel) ChannelServices.GetChannel("http");

    theChannel.Properties["proxyName"] = null;

    同样将上面的2行代码放在获取Remote Object的代码后面就可以了。

    (VI)The underlying connection was closed: Unable to connect to the remote server异常.

    可以从如下几个方面进行检测:

    (1)确认网络正常,并且在Client端可以通过IE访问到Remote Object。

    (2)确认Client的应用程序的配置文件URL正确访问Remote Object。

  • 相关阅读:
    ASP.NET Core 进程内(InProcess)托管
    ASP.NET Core 中的 Main 方法
    ASP.NET Core Web 项目文件
    5)
    4)
    单词
    html5单词
    3)
    2)
    1)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1738150.html
Copyright © 2020-2023  润新知