当前位置:首页 > 网站技术 > ASP.NET

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, 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:\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实现。

继续阅读
ViewState没了 WebForm还有意义吗?
ASP.NET合理充分利用DataSourceControl
ASP.NET开发上的经验来为WebForms辩护
ASP.NET2.0功能之重构(Refactoring)
VS2005中的WebSite和WebApplication区别
ASP.NET数组基础实例学习
ASP.NET2.0数据库绑定
不使用VS进行ASP.NET2.0 Membership配置管理
ASP.NET2.0角色及成员管理MemberShip
发表评论

昵称:
最新评论
暂时没有评论!