当前位置:首页 » 网站技术 » 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实现。

日期:2008-1-10 阅读统计:读取中.. 来自:蛙蛙池塘 作者:cnblogs.com/onlytiancai
文章搜索
继续阅读
ViewState与HiddenField控件
HiddenField控件的使用
ASP.NET前台使用__doPostBack函数调用后台事件
CSS改变DataGrid内边框的颜色
ASP.NET(C#)返回上一页(后退)代码
DataGrid中使鼠标到达的行显示不同的颜色
无组件Ajax效果实现
ASP.NET中Popup控件的使用方法
ASP.NET开发要抛弃ASP旧习和破烂
最新评论 -  查看全部评论
· 暂时没有评论!
发表评论
  • 昵称:
  • 匿名发表
Copyright © 2004-2008 智思网zhisi.net  All Right Reserved.
粤ICP备05002132号  
智思网:网络创业启思门户,助你开创事业!