我在设置WCF界面时遇到了一些困难。我可以很好地连接,但是一旦我开始发送某些数据,我就会得到以下异常:
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '01:39:59.9084817'.
通过查看其他一些问题,我发现这可能是因为超时效率低下。所以我将以下参数增加到100分钟只是为了踢。
tcpBinding.ReceiveTimeout = TimeSpan.FromMinutes(100);
tcpBinding.OpenTimeout = TimeSpan.FromMinutes(100);
tcpBinding.SendTimeout = TimeSpan.FromMinutes(100);
但是,在调用某个函数的同时抛出此异常,所以我不认为这是问题所在。但奇怪的是,异常总是显示的时间几乎与我放入这些参数的时间相同,无论实际传递的时间是多少。
我发现我可以发送标准类型,如object,string,int等,但每当我尝试发送自定义类型时,都会抛出此错误。这告诉我,它可能是一个不好的参考。这有意义吗?
更新: 有机会上传代码。
这是客户端:
namespace GenericWCF
{
/// <summary>
/// TODO: Update summary.
/// </summary>
[ServiceContract()]
public interface SimWCFInterface
{
[OperationContract()]
void SimpleMessage(string message);
[OperationContract()]
List<CustomObj> GetDataPoints();
}
}
和服务器端:
namespace DifferentNamespace
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// TODO: Update summary.
/// </summary>
[ServiceContract()]
public interface SimWCFInterface
{
[OperationContract()]
void SimpleMessage(string message);
[OperationContract()]
List<CustomObj> GetDataPoints();
}
和实际实施
namespace DifferentNamespace
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// TODO: Update summary.
/// </summary>
[ServiceContract()]
public interface SimWCFInterface
{
public void SimpleMessage(string message)
{
Debug.WriteLine("This is a simple message wcf");
MessageBox.Show(message);
}
public List<CustomObj> GetDataPoints()
{
List<CustomObj> points = new List<CustomObj>();
return points;
}
}
所以我真的没有什么特别的事情我想不到。 SimpleMessage
运行没问题。如果我更改GetDataPoints
以返回常规object
,那么它也可以正常工作。只有在我返回CustomObj
时才会出现此问题。我刚才注意到的一件事是客户端和服务器端存在于不同的命名空间中,那么这可能是个问题吗?另外,我使用tcp连接。我马上发布这段代码。
编辑:
tcp连接代码:
客户端
private string endPointAddress;
private NetTcpBinding tcpBinding;
public void Connect(string ipAddress, string portNumber, string interfaceName)
{
try
{
interfaceName = interfaceName.Substring(interfaceName.LastIndexOf(".") + 1);
endPointAddress = "net.tcp://" + ipAddress + ":" + portNumber + "/" + interfaceName;
tcpBinding = new NetTcpBinding();
tcpBinding.TransactionFlow = false;
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None;
tcpBinding.ReceiveTimeout = TimeSpan.FromMinutes(100);
tcpBinding.OpenTimeout = TimeSpan.FromMinutes(100);
tcpBinding.SendTimeout = TimeSpan.FromMinutes(100);
tcpBinding.ReliableSession.Ordered = false;
tcpBinding.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
tcpBinding.MaxReceivedMessageSize = 10000000;
tcpBinding.MaxBufferPoolSize = 10000000;
tcpBinding.MaxBufferSize = 10000000;
EndpointAddress endpointAddress = new EndpointAddress(endPointAddress);
_SimChannelFactory = new ChannelFactory<SimWCFInterface>(tcpBinding, endpointAddress);
_SimWCFInterface = _SimChannelFactory.CreateChannel();
//test connection...working
_SimWCFInterface.SimpleMessage("what a message");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
和服务器
static public void CreateSimHost(string IPAdd, string port, Type interfaceType, Type serviceType)
{
try
{
string interfaceName = interfaceType.ToString();
interfaceName = interfaceName.Substring(interfaceName.LastIndexOf(".") + 1);
// Create the url that is needed to specify where the service should be started
urlService = "net.tcp://" + IPAdd + ":" + port + "/" + interfaceName;
host = new ServiceHost(serviceType);
// The binding is where we can choose what transport layer we want to use. HTTP, TCP ect.
tcpBinding = new NetTcpBinding
{
TransactionFlow = false
};
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None; // <- Very crucial
tcpBinding.ReceiveTimeout = TimeSpan.MaxValue;
tcpBinding.SendTimeout = TimeSpan.MaxValue;
tcpBinding.ReliableSession.Ordered = false;
tcpBinding.ReliableSession.InactivityTimeout = TimeSpan.MaxValue;
// Add a endpoint
host.AddServiceEndpoint(interfaceType, tcpBinding, urlService);
host.Open();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}