这正是双工绑定的设计目的。你最好的两个选择是NetTcp绑定 http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.aspx or 轮询双工绑定 http://msdn.microsoft.com/en-us/library/system.servicemodel.pollingduplexhttpbinding(VS.95).aspx.
前者使用 TCP 协议,如果您的客户端不在您的网络上,则该协议可能不适合您的客户端。但是,它确实允许通过客户端启动的套接字进行双向通信。因此客户端不需要能够接受传入连接。我最近在一个项目中使用了这个,效果非常好。它的反应也非常灵敏。当客户端应用程序关闭时,服务器上的会话立即结束。
第二个选项 PollingDuplexBinding 包含在 Silverlight SDK 中。它使用客户端发起的“长”HTTP 请求。该请求等待需要发送给客户端的消息,当消息到达时,客户端请求返回。然后客户端向服务器发起一个新的 HTTP 请求。换句话说,客户端始终有一个待处理的 HTTP 请求。这可以很好地跨越防火墙,并且应该在与互联网客户端打交道时使用。但是,我发现它的响应速度不如 NetTcpBinding。我可能做错了什么,但似乎尝试向废弃的客户端会话发送回调需要一段时间才能“超时”。
下面是我最近的项目中使用 NetTcpBinding 进行双工通信的配置文件示例。请注意,除了对服务限制进行一些调整之外,我几乎使用此绑定的默认值。但有各种各样的事情 http://msdn.microsoft.com/en-us/library/ms731343.aspx您可以进行调整,例如 receiveTimeout、inactivityTimeout 等。
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="65535"
maxConcurrentSessions="65535"
maxConcurrentInstances="65535" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding maxConnections="65535">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="BroadcastService">
<endpoint address="" binding="netTcpBinding" contract="BroadcastService" />
</service>
</services>
</system.serviceModel>
</configuration>
[ServiceContract( CallbackContract = typeof( IBroadcastCallback ) )]
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]
public class BroadcastService : IDisposable
{
[OperationContract(IsInitiating=true)]
public long Subscribe( Guid clientID )
{
// clients call this to initiate the session
}
[OperationContract(IsOneWay = true)]
public void Publish( BroadcastMessage message )
{
// client calls this to broadcast a message to
// all other subscribed clients via callback
}
}
[ServiceContract( Name = "BroadcastCallback" )]
public interface IBroadcastCallback
{
[OperationContract( IsOneWay = true, AsyncPattern = true )]
IAsyncResult BeginBroadcast(BroadcastMessage Message, AsyncCallback callback, object state);
void EndBroadcast( IAsyncResult asyncResult );
} // interface