我写了一个WCF双工服务和客户端.一切正常,直到我尝试在客户端实现中调用.Demand().服务似乎是匿名调用回调方法.我想我错过了如何正确配置服务.
用于创建ServiceHost的代码;
ServiceHost duplex = new ServiceHost(new ServerWCallbackImpl());
NetTcpBinding secureBinding = new NetTcpBinding(SecurityMode.Message);
secureBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
duplex.AddServiceEndpoint(typeof(IServerWithCallback),
secureBinding,
"net.tcp://localhost:9080/DataService");
Console.WriteLine(Thread.CurrentPrincipal.Identity.Name); //<-- this correctly shows the current principal
duplex.Open();
if (duplex.State == CommunicationState.Opened)
((ServerWCallbackImpl)duplex.SingletonInstance).Send("Hello World!");
Run Code Online (Sandbox Code Playgroud)
用于创建客户端的代码;
CallbackImpl callbackInstance = new CallbackImpl();
NetTcpBinding secureBinding = new NetTcpBinding(SecurityMode.Message);
secureBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
DuplexChannelFactory<IServerWithCallback> cf = new DuplexChannelFactory<IServerWithCallback>(
callbackInstance,
secureBinding,
new EndpointAddress(requestingEndpointAddress));
cf.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
cf.Credentials.Windows.ClientCredential = (NetworkCredential)CredentialCache.DefaultCredentials;
IServerWithCallback srv = cf.CreateChannel(new InstanceContext(callbackInstance));
srv.InitiateConversation();
Run Code Online (Sandbox Code Playgroud)
客户实施:
public void MethodOnClient(string message)
{
Console.WriteLine(Thread.CurrentPrincipal.Identity.Name); // <-- anonymous
PrincipalPermission …Run Code Online (Sandbox Code Playgroud) 我想每秒从net tcp WCF服务向所有客户端发送通知消息,你可以说广播吗?
有用的答案之后
我编写了以下方法,将通知(心跳)发送给所有连接的用户
foreach (IHeartBeatCallback callback in subscribers)
{
ThreadPool.QueueUserWorkItem(delegate(object state)
{
ICommunicationObject communicationCallback = (ICommunicationObject)callback;
if (communicationCallback.State == CommunicationState.Opened)
{
try
{
callback.OnSendHeartBeat(_heartbeatInfo.message, _heartbeatInfo.marketstart,_heartbeatInfo.marketend, _heartbeatInfo.isrunning, DateTime.Now);
}
catch (CommunicationObjectAbortedException)
{
Logger.Log(LogType.Info, "BroadCast", "User aborted");
communicationCallback.Abort();
}
catch (TimeoutException)
{
Logger.Log(LogType.Info, "BroadCast", "User timeout");
communicationCallback.Abort();
}
catch (Exception ex)
{
Logger.Log(LogType.Error, "BroadCast", "Exception " + ex.Message + "\n" + ex.StackTrace);
communicationCallback.Abort();
}
}
else
{
DeletionList.Add(callback);
}
}
);
}
Run Code Online (Sandbox Code Playgroud)
我担心调用回调方法,因为客户端可能会关闭他的应用程序,但我使用try catch处理它,减少超时,并且并行发送广播,那就足够了吗?
我正在使用WCF(使用回调契约)和netTcpBinding创建聊天应用程序.我将该服务作为Windows服务托管,并通过客户端应用程序从其他计算机访问它.
我现在面临的问题是客户端连接在10分钟后进入故障状态,这似乎是某种超时发生.我已经尝试增加收到的超时并在服务和客户端发送超时但不起作用.
应该更改哪个设置以增加此超时期限以及应用程序,服务或客户端?
以下是我的配置文件,
服务
<system.serviceModel>
<services>
<service behaviorConfiguration="PeerTalk.Service.ChatServiceBehavior"
name="PeerTalk.Service.ChatService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="PeerTalk.Service.ServiceContracts.IChat">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:7920/ChatService" />
<add baseAddress="net.tcp://localhost:7921/ChatService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PeerTalk.Service.ChatServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding"
maxBufferSize="67108864"
maxReceivedMessageSize="67108864"
maxBufferPoolSize="67108864"
transferMode="Buffered"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:00:10"
sendTimeout="00:00:10"
maxConnections="100">
<readerQuotas maxDepth="64"
maxStringContentLength="67108864"
maxArrayLength="67108864"
maxBytesPerRead="67108864"
maxNameTableCharCount="16384"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows"/>
</security> …Run Code Online (Sandbox Code Playgroud) 我们有用于扑克桌面游戏的(多个)客户端-(一个)服务器架构。我们正在使用回调通道使用回调通知。
但有时由于互联网连接中断,该特定客户端与服务器断开连接,该特定客户端的 WCF 通道也进入故障状态,位于服务器的回调通道也发生故障。
设想 :
该客户端正在玩游戏,而互联网连接断开,该游戏已停止,但他的游戏窗口仍然保持打开状态,当他/她的互联网连接恢复时,该客户端从服务器中退出,但该玩家的游戏窗口仍然打开,该玩家可以当他/她的 WCF 频道退出时,不要做任何事情。
我们希望在他/她从服务器退出并抛出“ CommunicationObjectAbortedException ”异常时关闭该特定客户端的窗口。
我们不能使用以前的 WCF 通道的回调通道,因为它处于故障状态。因此,我们尝试在使用以下代码删除的同时在服务器中创建新的 callbackChannel:
操作上下文。当前.GetCallbackChannel();
但是这里 Current 显示“ NULL ”,因为该播放器的 WCF 通道被中止,因此它抛出“对象引用未设置为对象实例”的错误。
那么是否有任何解决方案可以使用中止的 WCF 通道的回调通道或恢复该 WCF 通道而不重新初始化它们或使用新通道调用该客户端?
我正在Azure上编写WCF服务.
在我的服务中,我需要在执行合同操作期间调用回调.当我尝试这样做时,将抛出异常并且客户端将被锁定.我认为这是因为通道打开合同操作,调用当前通道中的回调会锁定线程,对不对?我想为这种情况获得解决方案.
这是超时异常消息:
发送到net.tcp://127.255.0.0:8000/MytestWCFService的请求操作未在配置的超时(00:00:59.9889989)内收到回复.分配给此操作的时间可能是较长超时的一部分.这可能是因为服务仍在处理操作,或者因为服务无法发送回复消息.请考虑增加操作超时(通过将通道/代理强制转换为IContextChannel并设置OperationTimeout属性)并确保该服务能够连接到客户端.
编辑:代码示例
[ServiceContract(Namespace="testnamespace")]
public interface ICallback
{
[OperationContract(IsOneWay=true)]
void Callbackmethod();
}
Run Code Online (Sandbox Code Playgroud)
然后我在服务端实现IContract:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,
ConcurrencyMode=ConcurrencyMode.Reentrant,
AddressFilterMode=AddressFilterMode.Any)]
public class WCFService : IContract
{
public int Add(int a, int b)
{
int result = a + b;
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.Callbackmethod();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在回拨当前频道,它是一个双工频道.
我已经制作了一个WCF服务,可以对SQL数据库进行更改.
连接了一个客户端,其中有一个列表框显示该数据库中的数据.
此外,在客户端应用程序中,有一个文本框和一个按钮.单击按钮,文本框中的字符串也会添加到数据库和列表框中.
但是当我连接多个客户端时,只有进行更改的客户端才能在列表框中看到它们.
当我再次重新打开其他客户端时,新创建的字符串将添加到列表框中.
如何实时在所有客户端的列表框中进行这些更改?
我有一个WCF服务,它公开两个操作 - IncrementList()和GetList().客户端B连接到服务,调用GetList()并显示给用户.客户端A能够通过调用IncrementList()来更新此列表.
我希望客户端B在调用IncrementList()时得到通知,这样它可以再次调用GetList()来显示更新的数据.
您能否概述一下如何实现这一点?回调?复式?发布/订阅?
WCF 4.0中有哪些新功能可以帮助实现这种情况?

谢谢!