• 蛙蛙推荐:Remoting超时问题及初步解决方案


    测试一
    服务端

    class Program
    {
        
    static void Main(string[] args)
        
    {
            TcpChannel chan 
    = new TcpChannel(8080);
            ChannelServices.RegisterChannel(chan,
    false);
            RemotingConfiguration.RegisterWellKnownServiceType(
                
    typeof(ServerObject),
                
    "ServerObject", WellKnownObjectMode.Singleton);
            Console.WriteLine(
    "server is start");
            Console.Read();
            chan.StopListening(
    null);
            ChannelServices.UnregisterChannel(chan);
        }

    }

    public class ServerObject : MarshalByRefObject
    {
        
    public string SayHello(string name)
        
    {
            Thread.Sleep(
    5000);
            
    return string.Format("Hello {0}", name);
        }

    }


    客户端

    class Program
    {
        
    static void Main(string[] args)
        
    {
            
    try
            
    {
                Hashtable props 
    = new Hashtable();
                props[
    "name"= "tcp_rem";
                props[
    "timeout"= 1000;
                TcpChannel _tcpChannel 
    = new TcpChannel(props, nullnull);
                ChannelServices.RegisterChannel(_tcpChannel, 
    false);
                ServerObject so 
    = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://127.0.0.1:8080/ServerObject");
                Console.WriteLine(so.SayHello(
    "onlytiancai"));
            }

            
    catch (Exception ex)
            
    {
                Console.WriteLine(ex);
            }

            Console.Read(); 
        }

    }

    一秒超时后客户端就会报以下错误
    System.Net.Sockets.SocketException: 由于连接方在一段时间后没有正确答复或连接的主
    机没有反应,连接尝试失败。
    结论:tcpchannel的timeout设置对服务端处理时间过长时是起到超时作用的。

    测试二
    再做一个测试,把客户端连接的地址改成一个乱七八糟的远程地址。
    ServerObject so = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://192.192.192.192:8080/ServerObject");
    这时候客户端会hang 10秒以上,也有可能hang更久。
    结论:tcpchannel对连接网络慢或者网络层的执行时间太久是没有起到超时作用的。
    测试三
    再做一个测试,把我改进后的TcpClientTransportSink配置上,看看能不能起到超时的作用。
    配置文件如下

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      
    <system.runtime.remoting>
        
    <application >
          
    <channels>
            
    <channel ref="tcp">
              
    <clientProviders>
                
    <formatter ref="binary"/>
                
    <provider type="WawaSoft.Remoting.Channels.Tcp.TcpClientTransportSinkProvider,WawaRemoting" />
              
    </clientProviders>
            
    </channel>
          
    </channels>
        
    </application>
      
    </system.runtime.remoting>
    </configuration>

    客户端代码如下

    class Program
    {
        
    static void Main(string[] args)
        
    {
            
    try
            
    {
                RemotingConfiguration.Configure(
    "Client.exe.config"false);
                ServerObject so 
    = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://192.192.192.192:8080/ServerObject");
                Console.WriteLine(so.SayHello(
    "onlytiancai"));
            }

            
    catch (Exception ex)
            
    {
                Console.WriteLine(ex);
            }

            Console.Read();
     
        }

    }

    一秒后出现如下错误提示
    System.ApplicationException: connect timout

    Server stack trace:
       在 WawaSoft.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEnd
    Point) 位置 E:\huhao\project\RemotingTimeoutTest\WawaRemoting\Channels\RemoteCon
    nection.cs:行号 89

    结论:使用新的ClientTransportSink解决了因为网络问题hang太久的问题,但是目前的代码我只在connect上加了超时机制,send和receive还没有加超时机制,再有一个问题就是在同步调用上做超时必须另起个线程然后用join做超时,稳定性还得做压力测试来确认。

    新的ClientTransportSink和测试代码见以下链接。
    RemotingTimeoutTest.zip
    以上代码大多都是反射与.net fx,所以稳定性应该还是很好的,只修改了RemoteConnection类的CreateNewSocket方法,如下
    修改前

            private SocketHandler CreateNewSocket(EndPoint ipEndPoint)
            
    {
                Socket socket 
    = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                
    this.DisableNagleDelays(socket);
                socket.Connect(ipEndPoint);
                
    this._lkgIPEndPoint = socket.RemoteEndPoint;
                
    return this._socketCache.CreateSocketHandler(socket, this._machineAndPort);
            }

    修改后

            
    private SocketHandler CreateNewSocket(EndPoint ipEndPoint)
            
    {
                Socket socket 
    = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 
    1);
                Exception pingException 
    = null;
                DateTime now 
    = DateTime.Now;

                System.Threading.Thread pingThread 
    = new System.Threading.Thread(
                    
    delegate()
                    
    {
                        
    try
                        
    {
                            socket.Connect(ipEndPoint);
                            
    //这里不用beginConnect,太麻烦
                        }

                        
    catch (Exception ex)
                        
    {
                            pingException 
    = ex;
                        }

                    }
    );

                pingThread.Start();
                
    if (pingThread.Join(1000)){
                    
    if (pingException == null)
                    
    {
                        
    return this._socketCache.CreateSocketHandler(socket, this._machineAndPort);
                    }

                    
    else{throw pingException;}
                }

                
    throw new ApplicationException("connect timout");
            }
    改进;超时的部分想办法不用join事先,用一个waithandle实现。
  • 相关阅读:
    批量编译当前目录下4gl文件
    oracle数据库查看表
    Oracle中授权(grant)和同义词(synonym)
    Oracle中的instr()函数 详解及应用
    T100的程序错误提示方法
    六种 主流ETL 工具的比较
    oracle恢复数据到某个时间点
    Oracle统计一个小时内,一天内、一个星期内、一个月内、一年内的数据
    Linux top命令的用法详细详解
    Win10操作系统无法访问局域网共享文件夹的问题
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/1019013.html
Copyright © 2020-2023  润新知