WCF - 如何编写仅向特定客户端发布的发布者\订阅者服务?

2024-01-12

我正在以发布-订阅模式编写 WCF 服务。

当有人发布活动时,我不想立即将其发送给所有客户。

我希望能够为每个客户检查是否需要通知该客户该发布。

基本上,这将通过访问数据库并检查该客户端是否已使用这些参数订阅该特定事件来完成(无法提前完成,只需要根据数据库进行检查)。

目前我正在使用这个基于列表的发布订阅者 http://msdn.microsoft.com/en-us/library/ms752254.aspx示例,但它的工作方式是这样的 - 当发布事件时 - 客户端会话被单独触发以发送消息。

所以现在,我正在改变这一点:

 public void PriceChangeHandler(object sender, PriceChangeEventArgs e)
 {
     _callback.PriceChange(e.Item, e.Price, e.Change);
 }

对此:

 public void PriceChangeHandler(object sender, PriceChangeEventArgs e)
 {
     // Perform some database checks using BL if this client needs to be notified about this event

     // Only if answer is YES - call the callback function on that client
     _callback.PriceChange(e.Item, e.Price, e.Change);

     // Also - send the client an EMAIL + SMS
     _emailServer.SendEmail(e.Item);
     _smsServer.SendSMS(e.Item);
 }

两个问题:

这是正确的方法吗?我怎么知道“这个”客户是什么?客户是否应该通过我将存储的“订阅”方法向我发送凭据? 或者我应该实现一个自定义的“UsernameValidator”来存储主体?

难道我不应该有一个所有客户端的静态列表,我将其发送给我的 BL,并且 BL 将只返回我必须向其发送消息的客户端吗?


我认为首先回答这个问题会让生活变得更轻松:

我怎么知道“这个”客户是什么?

OperationContext.Current.GetCallbackChannel<T>

对于服务收到的每个调用,都会有一个进行调用的客户端通道,这将为您提供仅进行该调用的客户端的回调通道,这是您能够区分客户端的简单方法。

关于整个场景的方法,我首先会存储一个列表subscribers在静态的dictionary正如您自己建议的那样,还要保留每个客户端回调实例及其用户名:

private static Dictionary<IPriceChangeCallback, string> subscribers = new Dictionary<IPriceChangeCallback, string>();

Where IPriceChangeCallback是您的回调合约,字符串可以是唯一的用户名或任何标识符。现在您已经具备了区分客户端的基本能力,例如,假设您要将最后收到的消息发布给除发送消息的客户端之外的每个客户端,您将:

        lock (subscribers)
        {
            foreach (var _subscriber in subscribers)
            {
                if (OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>() == _subscriber.Key)
                {
                      //if the person who sent the last message is the current subscriber, there is no need to
                      //publish the message to him, so skip this iteration
                        continue;
                }
                else
                {
                       //GetCurrrentClient is a handy method, you can optionally include this  
                       //in your callbacks just to let your clients know who exactly sent the publication
                        _subscriber.Key.PriceChangeCallback(e.Item, e.Price, e.Change, GetCurrentClient());
                }
             }
         }

或者根据用户名来区分您的客户,理想情况下您也应该在数据库中拥有该用户名:

            lock (subscribers)
            {
                foreach (var _subscriber in subscribers)
                {
                    if(_subscriber.Value == "Jimmy86"))
                    {
                        //Identify a specific client by their username and don't send the notification to him
                        //here we send the notification to everyone but jimmy86
                        continue;
                    }
                    else
                    {
                        _subscriber.Key.PriceChangeCallback(e.Item, e.Price, e.Change, GetCurrentClient());
                    }
                }
            }

同样,每当您想要找出谁调用了服务操作,并告诉您的客户谁发送了该特定消息时,请使用GetCurrentClient()我之前提到的方法:

    private string GetCurrentClient()
    {
        return clients[OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>()];
    } 

这是正确的方法吗?

我不确定上面的方法是否明智,但每当我想保留客户端列表并对其调用某些方法时,我都会这样做。

客户是否应该通过我将存储的“订阅”方法向我发送凭据?

是的,这是一种常见的做法。有一个Subscribe()对您的服务进行操作,这将是您的客户想要加入您的服务时调用的第一个方法:

        [OperationContract(IsOneWay = true)]
        public void Subscribe(string username)
        {
            lock (subscribers)
            {
                subscribers.Add(OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>(), username);
            }
        }

几个月前我正在开发 Pub/Sub Silverlight 服务,我发现本文 http://tomasz.janczuk.org/2009/07/pubsub-sample-using-http-polling-duplex.html这是附带视频 http://channel9.msdn.com/Shows/SilverlightTV/Duplex-Communication-with-WCF-in-Silverlight-4-Silverlight-TV-34是无价的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WCF - 如何编写仅向特定客户端发布的发布者\订阅者服务? 的相关文章

  • rabbitmq 的 REST API

    有没有办法从 ajax 向 RabbitMQ 发送数据 我的应用程序由数千个 Web 客户端 用 js 编写 和 WCF REST 服务组成 现在我试图弄清楚如何为我的应用程序创建可扩展点 这个想法是有一个rabbitmq实例 它从放置在一
  • 我可以在 Windows 服务中托管(自托管)WCF 服务并通过 http 公开它吗?

    我是 WCF 新手 这可能吗 如果通过外部 Web 应用程序使用它 最好使用 IIS 和 http 即由 ASP NET MVC 应用程序托管的服务 吗 是的 您可以在 Windows 服务中托管 WCF 服务 http msdn micr
  • 如何为 WCF IErrorhandler 设置 web.config

    无法使用正确的 web config 将 IErrorHandler 集成到我的项目中 我有一个成功工作的 WCF 正在被 net 4 中的 webclient 使用 但是当尝试将 IErrorhandler 设置为全局错误记录器作为我所有
  • WCF流模式确实很慢

    我想知道为什么流模式下的 WCF 与缓冲模式相比确实很慢 基本上 我从服务器读取大量数据 数据库访问 然后通过 WCF 将大量数据传输到其他客户端 我通过比较两种不同的传输模式进行了一些测试和基准测试 我创建了 2 个端点 第一个正在使用t
  • WCF 服务支持文件 jsdebug 无法加载

    我有一个从客户端 JavaScript 调用的 WCF 服务 调用失败并出现 Service is null JavaScript 错误 WebDevelopment 帮助程序跟踪显示加载 jsdebug 支持文件的调用会导致 404 文件
  • 调试WCF时无法自动单步进入服务器

    我得到了可怕的 无法自动进入服务器 无法调试远程过程 这通常表明服务器上尚未启用调试 现在 我一直在读我需要添加
  • “服务 X 的应用程序端点为零”,除非我在代码中添加端点 - 为什么?

    我跟着这篇 MSDN 文章 http msdn microsoft com en us library ms733069 aspx完全创建托管在托管 NT 服务中的 WCF 服务 当我在服务控制台中单击 开始 时 我会在事件查看器中看到以下
  • 如何在没有 ServiceHost 类的情况下使用 WCF 创建简单的 Web 服务器?

    我已经开始学习 WCF 并希望通过直接使用通道堆栈创建一个简单的 Web 服务器来了解其内部结构 我在网络上找到了很多理论 但我希望看到一个接收和响应 httprequest 的工作示例代码 我可以使用任何浏览器进行测试 我希望能够通过组装
  • 使用 WCF 和 .NET 4.0 在 C# 中实现 SOAP 客户端

    我在 NET 4 0 中开始使用 WCF 时遇到问题 这是我的情况 我用 PHP 创建了一个小型 SOAP 服务器 我有一个 C 项目 我想在其中连接到此服务器并启动 SOAP 通信 我的问题是 我不知道如何在 C 中执行此操作 我找不到
  • 在方法/数据成员中向 WCF 添加限制

    我是 WCF 新手 我尝试对数据成员添加限制 例如在这个方法中 DataMember public string StringValue get return stringValue set stringValue value 我想设置最大
  • 有状态 WCF Web 服务

    我是 WCF 新手 我一直在尝试在 Web 服务中使用会话状态 我设法使用number http www codeproject com KB session SessionWithWS aspx msg 3227646 of http w
  • IIS6 中托管的 WCF 服务在生产中收到 404

    我已经构建了一个简单的 WCF 服务并将其部署到 IIS6 我注意到它可以在我的开发和登台环境中运行 但不能在生产环境中运行 每次我尝试点击服务元数据链接时 都会收到 404 页面 我检查了我能想到的所有 IIS 配置 它们是相同的 所以我
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • Silverlight 3 中 WCF 服务客户端代理的正确生命周期是什么?

    我在网上找到了我的问题的复杂答案 详细说明这个问题 我应该在每次异步调用时实例化服务客户端代理一次 还是在每个 Silverlight 应用程序中实例化一次 我是否应该显式关闭服务客户端代理 就像我在同步调用 WCF 服务的 ASP NET
  • Task.Delay 值得取消吗?

    我最近使用取消模式重新实现了一大堆异步 WCF 服务方法 我在很多地方都看到过这种模式的描述 您可以在其中等待Task WhenAny在已启动的任务和 Task Delay 上 当然 现有任务是不可取消的 但这有望在以后的版本中得到解决 就
  • AddressAccessDeniedException :无需 netsh 即可解决它?

    我遇到了异常AddressAccessDeniedException因为我的processus没有注册URL的权限 我首先以管理员身份运行我的程序 好的 它成功了 但我现在想要分发我的应用程序 并且我希望每个用户都能够运行它 而不必成为管理
  • 替换 WCF 默认 JSON 序列化

    是否可以替换 WCF 的默认 JSON 序列化 我目前正在使用webHttp行为 并通过application json作为 MIME 类型 特别是 我不喜欢默认情况下每个属性都是键 值对 例如 Key PropertyName Value
  • App.config 之外的 WCF ChannelFactory 配置?

    我有一个使用插件系统的 Windows 服务 我在插件基类中使用以下代码为每个 DLL 提供单独的配置 因此它将从plugin dll config string dllPath Assembly GetCallingAssembly Lo
  • 如何启动WCF语音聊天应用程序?

    我正在寻找开发 WCF 语音聊天应用程序 我想使用 WCF 服务来构建应用程序 Invite gt OK lt gt Audio flow lt

随机推荐