蛙蛙推荐:Remoting超时问题及初步解决方案
点击次数:23 次 发布日期:2008-11-26 10:35:59 作者:源代码网
|
源代码网推荐 测试一 源代码网推荐 服务端 源代码网推荐 源代码网推荐 源代码网推荐 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, null, null); 源代码网推荐 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:huhaoprojectRemotingTimeoutTestWawaRemotingChannelsRemoteCon 源代码网推荐 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实现。 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
