net.tcp 在以编程方式设置时有效,但在使用配置文件时无效
net.tcp works when programmatically set, but not when using config file
我正在尝试从以编程方式设置端点切换到使用配置文件。问题是当我使用配置文件时,没有抛出错误,但是tcp端口没有打开,客户端无法连接。
这是 netstat 显示以编程方式设置时打开的端口,然后是配置文件。
以下是我完整的示例客户端服务器和合约
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Server.CustomerService">
<endpoint
address="net.tcp://localhost:8081/CustomerService"
binding="netTcpBinding"
contract="Shared.ICustomerService"/>
</service>
</services>
</system.serviceModel>
</configuration>
服务器:
class ProgramService
{
static List<Customer> _customers = new List<Customer>();
static void Main(string[] args)
{
CreateCustomers();
Uri netTCPObject = new Uri("net.tcp://localhost:8081/CustomerService");
ServiceHost sessionHost = new ServiceHost(typeof(CustomerService), netTCPObject);
//ServiceHost sessionHost = new ServiceHost("Server.CustomerService"); //using the app.config
sessionHost.Open();
Console.WriteLine("Service is running");
Console.ReadLine();
sessionHost.Close();
}
private static void CreateCustomers()
{
_customers.Add(new Customer() { CustomerId = 1, FirstName = "Fred", LastName = "Flintstone" });
_customers.Add(new Customer() { CustomerId = 2, FirstName = "John", LastName = "Doe" });
_customers.Add(new Customer() { CustomerId = 3, FirstName = "Rebecca", LastName = "Johndaughter" });
_customers.Add(new Customer() { CustomerId = 4, FirstName = "Julie", LastName = "Herald" });
}
public class CustomerService : ICustomerService
{
public Customer GetCustomer(int customerId)
{
return _customers.FirstOrDefault(c => c.CustomerId == customerId);
}
public bool UpdateCustomer(Customer customer)
{
var curCust = _customers.FirstOrDefault(c => c.CustomerId == customer.CustomerId);
if (curCust != null)
{
curCust.FirstName = customer.FirstName;
curCust.LastName = customer.LastName;
}
else
{
_customers.Add(customer);
}
return true;
}
}
}
合同:
namespace Shared
{
[ServiceContract()]
public interface ICustomerService
{
[OperationContract]
Customer GetCustomer(int customerId);
[OperationContract]
bool UpdateCustomer(Customer customer);
}
[DataContract]
public class Customer
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int CustomerId { get; set; }
}
}
客户:
class ProgramClient
{
static void Main(string[] args)
{
//
NetTcpBinding binding = new NetTcpBinding();
EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost:8081/CustomerService");
ChannelFactory<ICustomerService> factory = new ChannelFactory<ICustomerService>(binding, endpoint);
ICustomerService service = factory.CreateChannel();
for (int i = 1; i < 5; i++)
{
Customer customer = service.GetCustomer(i);
Console.WriteLine(String.Format(" Customer {0} {1} received.", customer.FirstName, customer.LastName));
}
Console.ReadLine();
}
}
ServiceHost
构造函数有一个接受 Type
的重载和一个接受 object
的重载,可以是服务的类型或实例 class。
这意味着 new ServiceHost("someString")
将调用 object
重载,这将引发异常,因为 string
未实现服务。
您需要使用您的服务类型来调用它:
var serviceHost = new ServiceHost(typeof(CustomerService))
并且在配置中,使用 full name 类型:
<service name="ServiceNamespace.ProgramService.CustomerService">
我正在尝试从以编程方式设置端点切换到使用配置文件。问题是当我使用配置文件时,没有抛出错误,但是tcp端口没有打开,客户端无法连接。
这是 netstat 显示以编程方式设置时打开的端口,然后是配置文件。
以下是我完整的示例客户端服务器和合约 app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Server.CustomerService">
<endpoint
address="net.tcp://localhost:8081/CustomerService"
binding="netTcpBinding"
contract="Shared.ICustomerService"/>
</service>
</services>
</system.serviceModel>
</configuration>
服务器:
class ProgramService
{
static List<Customer> _customers = new List<Customer>();
static void Main(string[] args)
{
CreateCustomers();
Uri netTCPObject = new Uri("net.tcp://localhost:8081/CustomerService");
ServiceHost sessionHost = new ServiceHost(typeof(CustomerService), netTCPObject);
//ServiceHost sessionHost = new ServiceHost("Server.CustomerService"); //using the app.config
sessionHost.Open();
Console.WriteLine("Service is running");
Console.ReadLine();
sessionHost.Close();
}
private static void CreateCustomers()
{
_customers.Add(new Customer() { CustomerId = 1, FirstName = "Fred", LastName = "Flintstone" });
_customers.Add(new Customer() { CustomerId = 2, FirstName = "John", LastName = "Doe" });
_customers.Add(new Customer() { CustomerId = 3, FirstName = "Rebecca", LastName = "Johndaughter" });
_customers.Add(new Customer() { CustomerId = 4, FirstName = "Julie", LastName = "Herald" });
}
public class CustomerService : ICustomerService
{
public Customer GetCustomer(int customerId)
{
return _customers.FirstOrDefault(c => c.CustomerId == customerId);
}
public bool UpdateCustomer(Customer customer)
{
var curCust = _customers.FirstOrDefault(c => c.CustomerId == customer.CustomerId);
if (curCust != null)
{
curCust.FirstName = customer.FirstName;
curCust.LastName = customer.LastName;
}
else
{
_customers.Add(customer);
}
return true;
}
}
}
合同:
namespace Shared
{
[ServiceContract()]
public interface ICustomerService
{
[OperationContract]
Customer GetCustomer(int customerId);
[OperationContract]
bool UpdateCustomer(Customer customer);
}
[DataContract]
public class Customer
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int CustomerId { get; set; }
}
}
客户:
class ProgramClient
{
static void Main(string[] args)
{
//
NetTcpBinding binding = new NetTcpBinding();
EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost:8081/CustomerService");
ChannelFactory<ICustomerService> factory = new ChannelFactory<ICustomerService>(binding, endpoint);
ICustomerService service = factory.CreateChannel();
for (int i = 1; i < 5; i++)
{
Customer customer = service.GetCustomer(i);
Console.WriteLine(String.Format(" Customer {0} {1} received.", customer.FirstName, customer.LastName));
}
Console.ReadLine();
}
}
ServiceHost
构造函数有一个接受 Type
的重载和一个接受 object
的重载,可以是服务的类型或实例 class。
这意味着 new ServiceHost("someString")
将调用 object
重载,这将引发异常,因为 string
未实现服务。
您需要使用您的服务类型来调用它:
var serviceHost = new ServiceHost(typeof(CustomerService))
并且在配置中,使用 full name 类型:
<service name="ServiceNamespace.ProgramService.CustomerService">