Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用多个协定运行WCF ServiceHost_Wcf_Self Hosting - Fatal编程技术网

使用多个协定运行WCF ServiceHost

使用多个协定运行WCF ServiceHost,wcf,self-hosting,Wcf,Self Hosting,使用单个合约运行ServiceHost的效果很好,如下所示: servicehost = new ServiceHost(typeof(MyService1)); servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1"); servicehost.Open(); servicehost = new ServiceHost

使用单个合约运行ServiceHost的效果很好,如下所示:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.Open();
servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();
现在我想添加第二个(第三、第四,…)合同。我的第一个猜测是添加更多端点,如下所示:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.Open();
servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();
但这当然不起作用,因为在创建ServiceHost时,我可以将MyService1作为参数传递,也可以将MyService2作为参数传递——因此我可以向我的服务添加许多端点,但所有端点都必须使用相同的契约,因为我只能提供一个实现?

我觉得我没抓住重点。是否确定必须有某种方法为我添加的每个端点契约提供实现?

您需要在同一个类中实现两个服务(接口)

servicehost = new ServiceHost(typeof(WcfEntryPoint));
servicehost.Open(); 

public class WcfEntryPoint : IMyService1, IMyService2
{
    #region IMyService1
    #endregion

    #region IMyService2
    #endregion
}

仅供参考:我经常使用分部类使宿主类代码更易于阅读:

// WcfEntryPoint.IMyService1.cs
public partial class WcfEntryPoint : IMyService1
{
    // IMyService1 methods
}

// WcfEntryPoint.IMyService2.cs
public partial class WcfEntryPoint : IMyService2
{
    // IMyService2 methods
}

如果您对服务共享的合同满意,chili的回答就行了。如果要将它们分开,请尝试以下操作:

host1 = new ServiceHost(typeof(MyService1));
host2 = new ServiceHost(typeof(MyService2));

host1.Open();
host2.Open();

public class MyService1 : IMyService1
{
    #region IMyService1
    #endregion
}

public class MyService2 : IMyService2
{
    #region IMyService2
    #endregion
}

编辑:如Matt所述,这将要求每个服务/合同有多个端点

此答案是对chilltemp接受答案中评论的进一步回应

山姆,你真的应该确定为什么你需要10-50份合同,并尝试找到另一个解决方案。我查阅了Juval Lowy的WCF编码标准(在上找到),发现了以下参考资料:

3份服务合同 ... 4.避免与一名成员签订合同。 5.争取每个服务合同有三到五名成员。 6.每份服务合同的成员不得超过二十人。12可能是实际限制

他没有提到合同实现的限制(我可以找到),但我无法想象他将一项服务上的50份合同视为一种类似于最佳实践的东西。我发现一个很好的解决方案是将成员共享用于类似的功能

例如,如果您使用WCF服务对2个值执行数学运算,那么服务端可能有4个成员:加(x,y)、减(x,y)、乘(x,y)、除(x,y)。如果将这些元素组合到一个更通用的成员中,并使用对象来传递所需的数据,则可以轻松减少成员数量并提高可伸缩性。示例:PeformCalculation(obj),其中obj具有x、y和动作(加、减、乘、除)属性


希望这能有所帮助。

我目前面临着同样的问题,并决定执行下面的实现。我不确定拥有这么多服务契约是否会有任何性能问题,但在我的最终实现中,我可能会有大约10-15个服务契约,因此大约有10-15个ServiceHosts

我将所有WCF服务托管在一个Windows服务中

private void PublishWcfEndpoints()
{
    var mappings = new Dictionary<Type, Type>
    {
       {typeof (IAuthenticationService), typeof (AuthenticationService)},
       {typeof(IUserService), typeof(UserService)},
       {typeof(IClientService), typeof(ClientService)}
    };


    foreach (var type in mappings)
    {
        Type contractType = type.Key;
        Type implementationType = type.Value;

        ServiceHost serviceHost = new ServiceHost(implementationType);
        ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(contractType, ServiceHelper.GetDefaultBinding(),
                                                                  Properties.Settings.Default.ServiceUrl  + "/" + contractType.Name);
        endpoint.Behaviors.Add(new ServerSessionBehavior());

        ServiceDebugBehavior serviceDebugBehaviour =
            serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
        serviceDebugBehaviour.IncludeExceptionDetailInFaults = true;

        log.DebugFormat("Published Service endpoint: {0}", Properties.Settings.Default.ServiceUrl);

        serviceHost.Open();
        serviceHosts.Add(serviceHost);
    }

}
private void PublishWcfEndpoints()
{
var映射=新字典
{
{typeof(IAAuthenticationService),typeof(AuthenticationService)},
{typeof(IUserService),typeof(UserService)},
{typeof(IClientService),typeof(ClientService)}
};
foreach(映射中的变量类型)
{
类型contractType=Type.Key;
类型implementationType=Type.Value;
ServiceHost ServiceHost=新的ServiceHost(implementationType);
ServiceEndpoint端点=serviceHost.AddServiceEndpoint(contractType,ServiceHelper.GetDefaultBinding(),
Properties.Settings.Default.ServiceUrl+“/”+contractType.Name);
添加(新的ServerSessionBehavior());
ServiceDebugBehavior ServiceDebugBehavior=
serviceHost.Description.Behaviors.Find();
ServiceDebugBehavior.IncludeExceptionDetailInFaults=true;
DebugFormat(“已发布的服务端点:{0}”,Properties.Settings.Default.ServiceUrl);
Open();
serviceHosts.Add(serviceHost);
}
}

请随意评论这种类型的设置,如果有任何问题,尤其是与性能相关的问题。

将其拆分为一个基址和下面的多个服务/合同如何? 我现在不是在开发机器后面,而是:



每个服务实现自己的ServiceContract

您可以更改
公共类WcfEntryPoint:IMyService1、IMyService2


公共部分类WcfEntryPoint:IMyService1

公共部分类WcfEntryPoint:IMyService2


我通过使用类中的。每个合约仍然必须托管在它自己的
ServiceHost
中,但可以有一个
RoutingService
位于所有合约之上,并通过统一的“端点”呈现它们。我也写了一篇关于它的文章。示例代码也可以在上找到。

没有人记录enpoints。当使用多个(作为一个组,来自公共url,例如http)时,必须使用相同的绑定实例(而不是更多),即

您的样本:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();
应该只有一个新的Binding(),我通过http进行了测试

servicehost = new ServiceHost(typeof(MyService1));
 BasicHttpBinding binding = new BasicHttpBinding();
servicehost.AddServiceEndpoint(typeof(IMyService1),binding , "http://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), binding, "http://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();

我完全同意分部类在几个文件中实现几个契约。

我遗漏了什么,还是这里没有提到最简单的解决方案?最简单的解决方案是:不要为Web服务使用多个接口

但这并不意味着您仍然可以将接口分离。这就是为什么我们有接口继承

[ServiceContract]
public interface IMetaSomeObjectService : ISomeObjectService1, ISomeObjectService2
{
}
元接口从所有其他接口继承

[ServiceContract]
public interface ISomeOjectService1
{
    [OperationContract]
    List<SomeOject> GetSomeObjects();
}

[ServiceContract]
public interface ISomeOjectService2
{
    [OperationContract]
    void DoSomethingElse();
}
[服务合同]
公共接口IsoProject服务1
{
[经营合同]
列出GetSomeObjects();
}
[服务合同]
公共接口IsoProject服务2
{
[经营合同]
void DoSomethingElse();
}
那么服务就只有元接口了

public class SomeObjectService : IMetaSomeObjectService
{
   public List<SomeOject> GetSomeObjects()
   {
       // code here
   }

   public void DoSomethingElse()
   {
       // code here
   }
}
公共类SomeObjectService:IMetaSomeObjectService
{
公共列表GetSomeObjects()
{
//代码在这里
}
公共无效DoSomethingElse()
{
//代码在这里
}
}

Dang。我需要的不仅仅是两杯