我正在使用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采用相同的方法。