问题标签 [wcf-callbacks]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
1002 浏览

c# - Thread.CurrentPrincipal 不在 WCF 客户端回调中保留

我有一个基于 netTcpBinding 的双工 WCF 服务,该服务使用订阅模型,其中客户端将使用订阅/取消订阅方法通过回调实现订阅服务。

该服务有一个自定义 IAuthorizationPolicy,它对来自数据库的用户进行身份验证,并将默认线程主体设置为 IAuthorizationPolicy.Evaluate() 方法中的自定义主体。

该服务在 IIS 7.5 中作为服务运行,在 LOCALSYSTEM 身份下,Windows 7

首先,这是客户端(WinForms)对用户进行身份验证的方式:

  1. 显示登录表单以要求提供凭据
  2. 在不同的端点上调用另一个身份验证服务来验证用户凭据
  3. 使用 AppDomain.SetThreadPrincipal 设置默认线程主体

我面临的问题是,在回调线程中,并且仅在回调线程中, Thread.CurrentPrincipal 被重置为匿名 GenericPrincipal 对象,并且我在身份验证后设置的自定义主体不会传播。


更新:如果我将securityMode和clientCredentialType设置为“None”,则主体会按预期传播,显然这与安全配置有关,我尝试了很多配置组合但没有运气。


更新:我已经包含了一个重现该问题的示例项目。

该解决方案简单明了,一切都已配置并运行,只需点击几下,您的宝贵时间只需几分钟,它包含 5 个项目:

  1. PM.Services - WCF 服务项目
  2. PM.Contracts - 包含服务合同的库
  3. Client/Broadcaster - 控制台应用程序通过服务向其他客户端广播。
  4. 客户端/侦听器- 订阅服务/侦听广播的控制台应用程序(这是重置 Thread.CurrentPrincipal 的位置)
  5. Client/Shared - 两个客户端之间共享的库,包含回调实现和服务创建代码。

要在您的机器上配置服务(假设机器上已启用 IIS7 或更高版本),解决方案根文件夹包含两个批处理文件:

InstallService.bat:这批将:

  • 在您的计算机上启用以下 Windows 功能及其父功能(如果尚未启用): Windows Communication Foundation HTTP ActivationWindows Communication Foundation Non-HTTP Activation,以启用 WCF 和 net.tcp。

  • 将在 TrustedPeople 存储中创建和添加服务证书。

  • 将为将侦听的服务创建一个网站:7359 (http) 和 7357 (net.tcp)

  • 将在 LOCALSYSTEM 身份下创建一个 ApplicationPool (以避免在测试过程中出现权限问题)

  • 将在 c:\inetpub\WCFCallbackSample 中创建一个文件夹并将服务输出复制到其中。

UninstallService.bat:此批次将:

  • 从 TrustedPeople 存储中删除服务证书。

  • 卸载服务网站。

  • 删除网站文件夹。

运行示例解决方案:

  • 构建解决方案

  • 使用 InstallService.bat 安装服务。

  • 调试/运行解决方案以运行两个服务消费者(Client\Broadcaster、Client\Listener)

  • 从广播者发送消息

  • 在侦听器中,您会注意到回调线程标识(打印在控制台上)与应用程序启动时 SetThreadPrincipal 设置的主线程标识不同。


初始帖子中的代码:

服务接口:

服务实现:

回调实现:

更新服务配置

更新工厂方法我使用以下方法创建服务:

PMClientPrincipal 是我的 IPrincipal 实现,PMClientPrincipal.Current是一个静态属性,它只是将当前线程主体转换为 PMClientPrincipal

UPDATE管理客户端订阅的类(在服务中使用)

更新回调方法的调用堆栈

0 投票
1 回答
4330 浏览

c# - C# WCF 多客户端

我制作了一个对 SQL 数据库进行更改的 WCF 服务。

有一个客户端连接,有一个列表框显示来自该数据库的数据。

此外,在客户端应用程序中,有一个文本框和一个按钮。通过单击按钮,来自文本框的字符串被添加到数据库和列表框中。

但是当我连接多个客户端时,只有进行更改的客户端才能在列表框中看到它们。

当我再次重新打开其他客户端时,新创建的字符串将添加到列表框中。

如何实时在所有客户端的列表框中进行这些更改?

0 投票
0 回答
657 浏览

.net - WCF服务回调调用的奇怪死锁

我在 WCF 服务上有一个死锁问题,我不明白为什么,因为每个调用都在同一个锁上同步。这是我的客户端/服务配置。

绑定="netTcpBinding"

服务配置:ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Reentrant,UseSynchronizationContext = false)

回调配置:CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,UseSynchronizationContext = false)

代码(我已经简化了类和方法名称以进行澄清):

回调以异步方式在单独的线程中调用。当我从客户端调用DoAction()方法时,出现死锁并且出现 TimeoutException:

2015-01-16 10:42:17,463 [8] 错误 - (OrderManagerViewModel.cs:311) - CancelOrder : System.TimeoutException: Cette op곡tion de demande envoyꥠ࡮et.tcp://localhost:8002/NetsOrderManagerServiceRemote/ n'a pas re赠de r걯nse dans le dꭡi informti (00:00:05)。Le temps allou顠 cette op곡tion fait peut-뵲e partie d'un dꭡi d'attente plus long。Ceci peut 뵲e d fait que le service est toujours en cours de traitement de l'op곡tion ou qu'il n'a pas pu envoyer un message de r걯nse。Envisagez d'augmenter le dꭡi d'attente de l'op곡tion (en diffusant le canal/proxy vers IContextChannel et en dꧩnissant la propri굩 OperationTimeout) et v곩fiez que le service peut se connecter au client。

服务器堆栈跟踪:
ࡓystem.ServiceModel.Dispatcher.DuplexChannelBinder.SyncDuplexRequest.WaitForReply(TimeSpan timeout)
ࡓystem.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout)
ࡓystem.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway , ProxyOperationRuntime 操作, Object[] ins, Object[] outs, TimeSpan timeout)
ࡓystem.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs
) Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
ࡓystem.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

[0] 处重新抛出异常:
系统.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
系统.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 类型
) .Service.IOrderManager.CancelOrder(ICancelOrderRequest cancelRequest)
ࡎets.Core.Client.Wcf.OrderServiceWcfClient.RemoteOrderManagerServiceProxy.CancelOrder(ICancelOrderRequest cancelRequest) dans c:\dev\GitProjects\NetsCoreLibProject\NetsCoreLib\Nets.Core.Client.Wcf.OrderServiceWcfClient\RemoteOrderManagerServiceProxy .cs:线 340
ࡎets.Core.Prototype.Client.ViewModels.OrderManagerViewModels.OrderManagerViewModel.CancelOrder(Object parameter) dans c:\dev\GitProjects\NetsCoreLibProject\NetsCoreLib\Nets.Core.Prototype.Client\ViewModels\OrderManagerViewModels\OrderManagerViewModel.cs:ligne 302

下面的服务器日志显示DoAction()回调执行之前的返回。

做动作通话记录:

2015-01-16 11:13:57,342 [27] INFO - (RemoteOrderManagerService.cs:195) - CancelOrder:RemoteOrderService:服务器调用的 CancelOrder 操作 2015-01-16 11:13:57,342 [27] INFO - (RemoteOrderManagerService。 cs:203) - CancelOrder : RemoteOrderService : CancelOrder action return report=[CancelOrder report netsd2dce|无法验证过滤器订单一致性检查 2015-01-16 11:13:57,342 [27] 信息 - (RemoteOrderManagerService.cs:208) - CancelOrder : RemoteOrderService : CancelOrder 动作返回完成

CallbackAfterDoAction 通话记录:

2015-01-16 11:13:57,342 [EventQueue-ThreadDispatcher-HighPriorityEventQueue-2] 信息 - (OrderManagerService.cs:451) - DispatchErrorOnOrder:订单 NetsOrderId [netsd2dce] 2015-01-16 11:13:57,342 [ EventQueue-ThreadDispatcher-HighPriorityEventQueue-2] INFO - (Order.cs:760) - OnCancelAck : OnCancelAck [[Order #ob_,ba3 (netsd2dce) BUY 1 [TOTF.PA] @ 47]|Owner=[]]: 无法执行request=[CANCEL] 原因 Order=[[Order #ob_,ba3 (netsd2dce) BUY 1 [TOTF.PA] @ 47]|Owner=[]] 处于最终状态=[CANCELLED] 2015-01-16 11:13 :57,343 [EventQueue-ThreadDispatcher-HighPriorityEventQueue-2] 信息 - (Order.cs:765) - OnCancelAck : OnCancelAck [[Order #ob_,ba3 (netsd2dce) BUY 1 [TOTF.PA] @ 47]|Owner=[]] : 从 Nets.Core.Service.Remote.RemoteOrderManagerService 调用

但是:当我评论服务上的回调调用时, DoAction() 方法正确执行。当死锁发生时,它就像在 DoAction 方法返回之前调用回调一样。我不明白会发生什么,因为调用的每个方法都在同一个锁上同步。

PS:如果我在回调调用之前添加睡眠:

死锁在 Sleep(3) 之前永远不会发生,但对于值 < 3 ms 时,就会发生死锁。==> 那么问题是为什么回调是在 DoAction() 方法的返回语句之前处理的,而日志却相反?

0 投票
1 回答
581 浏览

.net - 为什么我的 WCF 回调超时?

我有以下服务和回调合同(删节):

服务合同:

回调合约:

服务实施:

服务消费者:

SchedulerViewModel绑定到一个带有文本框和按钮的简单窗口,通过它的和Status属性StopScheduler。WCF 由一个简单的控制台应用托管,用于调试:解决方案设置为先启动服务主机(控制台应用),然后再启动 WCF 应用。

当我单击主应用程序窗口上的按钮时,我希望调用该命令,即调用proxy.Stop();. 这应该改变服务状态的状态并调用回调。我认为确实如此,但回调超时。调试器挂了proxy.Stop();,最后我得到错误信息:

发送到 http://localhost:8089/TestService/SchedulerService/的此请求操作在配置的超时 (00:00:59.9990000) 内未收到回复。分配给此操作的时间可能是较长超时的一部分。这可能是因为服务仍在处理操作,或者因为服务无法发送回复消息。请考虑增加操作超时(通过将通道/代理转换为 IContextChannel 并设置 OperationTimeout 属性)并确保服务能够连接到客户端。

当我SchedulerViewModel在控制台应用程序中使用时,回调工作正常,并且视图模型Status: Stopped在控制台窗口中打印。一旦我涉及其他线程,回调就不再起作用。其他线程正在提升视图模型OnPropertyChanged以更新绑定的文本框,我不知道是否有更多线程参与启用/禁用命令。

调用的服务方法中的任何内容最多都不应超过毫秒,我相信我正朝着正确的方向前进,相信这是一个线程和/或 UI 挂起问题,因为我在进行研究时看到了类似的问题。大多数是完全不同的场景和深入的技术解决方案。

为什么会发生这种情况,我是否无能为力,使用相当标准的 WPF 和 WCF 基础结构和函数来启用此回调?我可悲的选择是让服务将状态写入文件,并让视图模型观察文件。这是一个肮脏的解决方法?

0 投票
0 回答
301 浏览

c# - 回调合约和绑定

我在网站上有我的服务。我尝试运行这个示例,首先只是服务器部分::我需要采取哪些步骤才能使用 WCF 回调?

但我收到此消息:“合同需要 Duplex,但绑定 'BasicHttpBinding' 不支持它或未正确配置以支持它。”

Web.config 文件没有诸如“BasicHttpBinding”之类的定义。它只有更一般的定义。我是否必须在其中添加行,或者有更简单的方法。非常感谢。

0 投票
1 回答
233 浏览

c# - WCF 回调不会触发

我有一个带有回调的 WCF 服务。然后我调用一个回调函数,一切都很好,除了:然后我尝试传递一个列表,回调没有被调用,但也没有抛出异常。回调对象正在工作,因为其他一切工作正常,我也可以推送与列表中的类对象相同的类对象。Class 对象被声明为 a[DataContract]并且 Properties 被声明为[DataMember]。我还遍历了列表,它通常由实体框架生成。

0 投票
1 回答
1186 浏览

wcf - WCF netTcpBinding issue: Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it

I'm trying to create a callback in WCF service. Service so far was using basicHttpBinding, so I want to add another end point for netTcpBinding. Service is already hosted in IIS. First It was hosted in IIS 6, but then I installed IIS 7.

So, I'm getting the following error:

The requested service, 'net.tcp://localhost:1801/MyServiceName.svc/NetTcpExampleAddress' could not be activated. See the server's diagnostic trace logs for more information.

When seeing the log, this is the message:

enter image description here

So the main error is:

Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.

Here are my config files:

My Web.config for the server:

My App.config for the client:

Settings in my IIS:

enter image description here

enter image description here

If there are any other pieces of code that you need, please let me know and I'll update the question.

EDIT 1:

Here are more details from the code, of how I'm calling the service from the client (on client side):

where interfaces (on server side) are defined as:

and service (on server side) is defined as:

My methods so far are just a demo. Once the error related to this question is fixed, then I'll start with developing the methods.

0 投票
0 回答
766 浏览

wcf - 如何在 ASP.NET 核心应用程序中接收从 WCF 服务到 WebApi 的双工回调?

我正在尝试将来自 WCF 服务的双工回调接收到我的 Web api 操作中。但不知何故,这是行不通的。我无法在 web api 中获得回调。

如果我使用控制台应用程序而不是 asp.net 核心应用程序,那么控制台应用程序会收到回调。因此,WCF 服务设置正确并且工作正常。不知何故,问题出在 web api 控制器中(特别与回调处理程序有关)

请建议我应该如何在 web api 中编写回调处理程序?

这些是我到目前为止尝试过的步骤-

Step1:使用 netTcpBinding 创建 WCF 服务

Step2:使用WCF Connected Service扩展将服务参考代码生成到本文提到的名为reference.cs的文件中

第3 步:为了创建工具生成的 WCF 客户端类型的实例并与您的 Web 服务通信,我在我的 Web api 控制器中编写了以下代码 -

我的环境:

Visual Studio 2015 Update3 + WCF 连接服务扩展

带有 netTcpBinding 的 WCF 服务

ASP.NET 核心 1.0 应用程序

0 投票
0 回答
112 浏览

wcf - WCF 服务回调与用于 Web 通知的 Web 推送 API 集成

即使未打开浏览器,我的 Web 应用程序也需要通知(来自 WCF 服务回调)。

我将从网络中托管的 WCF 服务的 WCF 服务回调中获得通知源/事件。

我遇到了 Web Push API 和 Service Workers 概念,它们给了我预期的行为(甚至在浏览器关闭时通知)。

Push API 可以将通知发送给 service worker,然后它可以处理。即使没有为通知打开浏览器,也只有 service worker 可以被激活。

我怀疑我是否可以为服务回调托管 WCF 服务,即使与服务工作者相比,浏览器已关闭。

如何实现这个场景?我在我的 web 应用程序中的 WCF 服务回调中获得的通知 -> 传递给推送 api -> 服务工作者 -> 通知显示。

0 投票
0 回答
304 浏览

c# - WCF 回调死锁即使使用“UseSynchronizationContext = false”

我遇到了一个我不太理解的问题。

该问题与客户端线程之间的同步有关,但我找不到其根本原因。我创建了一个小演示来模拟这个问题,所以它会更容易解释。

服务联系人:

回调合约:

服务实施:

调用Test1方法时的服务将使用提供给方法的值引发回调Test1

客户代码:

客户端首先注册到服务器的回调(注意异步注册调用 -这就是问题)然后调用Test1. 这里的调用Test1永远不会返回

  • RegisterAsync同步调用(使用.Wait())时,调用Test1不会死锁。
  • 在服务器中调用Test1通行证没有任何问题。
  • 使用的绑定是 NetNamedPipeBinding:

    绑定_defaultBinding = new NetNamedPipeBinding { MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue, ReceiveTimeout = TimeSpan.MaxValue, SendTimeout = TimeSpan.MaxValue, CloseTimeout = TimeSpan.MaxValue };

我认为将UseSynchronizationContext属性设置为false(在 theServiceBehaviourAttribute和 in 中CallbackBehaviourAttribute)应该可以解决这个问题。