使用WCF调用两次函数

时间:2015-06-02 12:40:18

标签: c# wcf

我正在使用DuplexChannelFactory将我的客户端连接到我的服务器,我现在要做的是将服务器连接到将在服务器上注册的每个客户端。但每次启动客户端时,我的“init()”函数都会运行两次。而我在服务器端的DuplexChannelFactory不起作用。

以下是我为客户打开服务器的方法:

host = new ServiceHost(typeof(NewServeur.NewServeur));
host.Open();

使用App.Config:

 <system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MEX">
                <serviceMetadata />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="MEX" name="NewServeur.NewServeur">
            <endpoint address="IProxyNewServeur" binding="netTcpBinding"
                bindingConfiguration="configWin" name="NetTcpEndpoint" contract="ProxyNewServeur.IProxyNewServeur" />
            <endpoint address="MEX" binding="mexTcpBinding" bindingConfiguration=""
                name="MexTcpEndpoint" contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="net.tcp://192.156.142.176:8080/" />
                </baseAddresses>
            </host>
        </service>
    </services>
  <bindings>
    <netTcpBinding>
      <binding name="configWin">
        <security mode="None"></security>
      </binding>
    </netTcpBinding>
  </bindings>
</system.serviceModel>

以下是我将客户端连接到服务器的方法:

void init()
{
   ServiceCablingCallback ServiceCablingCallback = new ServiceCablingCallback();
   ServiceCablingCallback.ClientNotified += ServiceCablingCallback_ClientNotified;
   this._instanceContext = new InstanceContext(ServiceCablingCallback);
   this.factory = new DuplexChannelFactory<ProxyNewServeur.IProxyNewServeur>(_instanceContext, "configClient");
   this._serviceCablingClient = factory.CreateChannel();
   this._clientId = _serviceCablingClient.Subscribe();
}

使用其App.Config

<system.serviceModel>
<client>
  <endpoint address="net.tcp://192.156.142.176:8080/IProxyNewServeur"
    binding="netTcpBinding" bindingConfiguration="configWin" contract="ALSTEF.Cabling.ProxyNewServeur.IProxyNewServeur"
    name="configClient" />
</client>
<bindings>
  <netTcpBinding>
    <binding name="configWin">
      <security mode="None" />
    </binding>
  </netTcpBinding>
</bindings>

这很好用,但现在我想做相反的事情,这意味着将服务器连接到客户端。为了做到这一点,我在客户的最后一行之前添加了这些行:

 host = new ServiceHost(typeof(Service), new Uri(_serviceCablingClient.getIp()));
 host.Open();

getIp()返回我的客户端的IP地址+端口4242。

这是客户端App.config

 <behaviors>
  <serviceBehaviors>
    <behavior name="MEX">
      <serviceMetadata />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service behaviorConfiguration="MEX" name="Client.Model.Service">
    <endpoint address="IClientFunction" binding="netTcpBinding" bindingConfiguration="ClientConfig"
      name="NetTcpEndpoint" contract="ProxyNewServeur.IClientFunction" />
    <endpoint address="MEX" binding="mexTcpBinding" bindingConfiguration=""
      name="MexTcpEndpoint" contract="IMetadataExchange" />
  </service>
</services>

<!-- in the bindings html tag -->
 <binding name="ClientConfig">
   <security mode="None" />
 </binding>

我通过添加这些行来修改_serviceCablingClient.Subscribe()(所以在服务器中)

public Guid Subscribe()
{
   ProxyNewServeur.INewServeurCallback callback =
            OperationContext.Current.GetCallbackChannel<ProxyNewServeur.INewServeurCallback>();

   System.ServiceModel.Channels.RemoteEndpointMessageProperty endpointProperty = 
            OperationContext.Current.IncomingMessageProperties[System.ServiceModel.Channels.RemoteEndpointMessageProperty.Name] as System.ServiceModel.Channels.RemoteEndpointMessageProperty;


   Guid clientId = Guid.NewGuid();
   if (callback != null)
   {
      lock (clientsCallback)
      {
         clientsCallback.Add(clientId, callback);
      }
   }

   /* code I added */
   string addr = "net.tcp://" + endpointProperty.Address + ":" + "4242" + "/IClientFunction";

   ClientCallback cb = new ClientCallback();
   var Okvp = new KeyValuePair<Guid, DuplexChannelFactory<ProxyNewServeur.IClientFunction>>(clientId,
   new DuplexChannelFactory<ProxyNewServeur.IClientFunction>(new InstanceContext(cb), "configServer",
   new EndpointAddress(addr)));
   this.DictClient.Add(Okvp, Okvp.Value.CreateChannel());
   this.DictClient[Okvp].CreateCallbackChannel();
   /* end code I added */
}

我将其添加到服务器App.config

<client>
    <endpoint binding="netTcpBinding" bindingConfiguration="ClientConfig" contract="ProxyNewServeur.IClientFunction" name="configServer" />
</client>  

<!-- in the bindings html tag -->
<binding name="ClientConfig">
  <security mode="None" />
</binding>

以下是我定义ProxyServeur文件的方法

namespace ProxyNewServeur
{
    [ServiceContract(CallbackContract = typeof(INewServeurCallback))]
    public interface IProxyNewServeur
    {
       [OperationContract]
       Guid Subscribe();
       [OperationContract]
       string getIp();
    }

    [ServiceContract]
    public interface INewServeurCallback
    {
       [OperationContract(IsOneWay = true)]
       void HandleMessage(Message message);
    }

    [ServiceContract(CallbackContract = typeof(IClientCallback))]
    public interface IClientFunction
    {
       [OperationContract(IsOneWay = true)]
       void CreateCallbackChannel();
    }

    [ServiceContract]
    public interface IClientCallback
    {
       [OperationContract(IsOneWay = true)]
       void BroadcastToServer(bool isActive, Guid ClientId);
    }
}

现在当我启动客户端时

DictClient[Okvp].CreateCallbackChannel();

将无效,我将在

中进行两次
init()
{ /* code*/
} 

功能

我不知道为什么会这样。我在测试项目中做了完全相同的事情并且工作正常。

修改

事实证明,你不能拥有DuplexChannelFactory&lt;&gt;和ServiceHost在同一个方法中。所以我做的是我添加了一个只有一个属性的新类“DoubleConnection”。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class DoubleConnection : ProxyNewServeur.IClientFunction
{
    public ServiceHost host;

    public void CreateCallbackChannel()
    {}
    public void isActive()
    {}
}

并在我删除的init()函数中

 host = new ServiceHost(typeof(Service), new Uri(_serviceCablingClient.getIp()));
 host.Open();

并添加了

 varClass = new DoubleConnection();
 varClass.host = new ServiceHost(typeof(DoubleConnection), new Uri(_serviceCablingClient.getIp()));
 varClass.host.Open();

我现在工作正常,但我仍然不知道为什么你不能拥有DuplexChannelFactory&lt;&gt;和ServiceHost采用相同的方法。

0 个答案:

没有答案