Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用WCF回调和asp.net实现发布/订阅模式_Asp.net_Wcf_Callback_Publish Subscribe - Fatal编程技术网

使用WCF回调和asp.net实现发布/订阅模式

使用WCF回调和asp.net实现发布/订阅模式,asp.net,wcf,callback,publish-subscribe,Asp.net,Wcf,Callback,Publish Subscribe,这是我第一个使用WCF的web应用程序。所以请作为一个新人来指导我 我正在尝试使用WCF回调来实现发布/订阅模式。我现在想把这个消息从UserA发送给UserB或UserA给每个客户机。我从中得到了一个例子 在我的应用程序中,我使用ASP.NET作为客户端连接WCF服务,但在订阅WCF服务时发现了一个问题 WCF服务不包含任何其他客户端对象。因此,当我调用GetAllClients(_guid)时,它将只返回一个本身就是它的客户机 下面是ASP.NET页面中的代码(我将每个控件都放在update

这是我第一个使用WCF的web应用程序。所以请作为一个新人来指导我

我正在尝试使用WCF回调来实现发布/订阅模式。我现在想把这个消息从UserA发送给UserB或UserA给每个客户机。我从中得到了一个例子

在我的应用程序中,我使用ASP.NET作为客户端连接WCF服务,但在订阅WCF服务时发现了一个问题

WCF服务不包含任何其他客户端对象。因此,当我调用
GetAllClients(_guid)
时,它将只返回一个本身就是它的客户机

下面是ASP.NET页面中的代码(我将每个控件都放在
updatePanel
中)

问题是:

  • 是否可以使用ASP.NET和WCF回调实现此发布/订阅?(我已经在Windows应用程序上试用过,效果很好)

  • 若可能的话,我如何保持连接到WCF服务的所有客户端,以便使用这些GuId调用回调方法


  • 谢谢。

    我不知道您为什么不获取客户列表-您应该这样做,但您的代码存在更严重的问题

    您不能在ASP.NET应用程序中使用WCF回调。它不能工作,因为页面的存在只是为了服务单个HTTP请求——这意味着它很可能只存在一小部分秒,所以您的注册也是如此。即使您能够获得客户端列表,您也无法调用
    OnRegister
    OnMessageSending
    ,因为将没有代理侦听这些调用

    即使您在请求处理后强制代理活动,它仍然只会通知代码隐藏,而不会通知您在客户端浏览器中呈现的页面

    另一个问题是,它只能与net.pipe或net.tcp绑定一起工作。它不适用于wsDualHttp。在使用wsDualHttp时,从同一台机器打开多个双工客户端是非常困难的


    你完全错了。您需要的是从客户端浏览器到asp.net的AJAX轮询,这将在您的聊天系统中调用简单服务。

    我不知道为什么您没有得到客户端列表-您应该这样做,但您的代码存在更糟糕的问题

    您不能在ASP.NET应用程序中使用WCF回调。它不能工作,因为页面的存在只是为了服务单个HTTP请求——这意味着它很可能只存在一小部分秒,所以您的注册也是如此。即使您能够获得客户端列表,您也无法调用
    OnRegister
    OnMessageSending
    ,因为将没有代理侦听这些调用

    即使您在请求处理后强制代理活动,它仍然只会通知代码隐藏,而不会通知您在客户端浏览器中呈现的页面

    另一个问题是,它只能与net.pipe或net.tcp绑定一起工作。它不适用于wsDualHttp。在使用wsDualHttp时,从同一台机器打开多个双工客户端是非常困难的


    你完全错了。您需要的是从客户端浏览器到asp.net的AJAX轮询,这将在您的聊天系统中调用简单服务。

    感谢您的快速回复。据我所知,没有办法用asp.net和wcf实现发布/订阅,对吗?如果是,我可能会寻找其他方法来进行POC。如果你想为应用程序的每个客户端(针对浏览器)进行双工通信,那么你肯定应该寻找其他解决方案——正如我已经提到的,你需要AJAX轮询。如果我使用AJAX轮询,我不太确定是否会出现性能问题。因为我在同一时间拥有1000多名活跃用户。你觉得怎么样?这要看情况。如果你每秒打10次电话,这可能是个问题。如果你每5秒钟打一次电话,这不会是问题。您也可以查看Silverlight。我对异步轮询做了一些研究,发现了wcf的长轮询。我不太确定它是否适合我的问题。关于你对silverlight的建议,我目前还不知道。我是否必须在客户端计算机上安装任何程序/组件才能使用该技术?顺便说一句,我会试试你的建议。再次感谢您。谢谢您的快速回复。据我所知,没有办法用asp.net和wcf实现发布/订阅,对吗?如果是,我可能会寻找其他方法来进行POC。如果你想为应用程序的每个客户端(针对浏览器)进行双工通信,那么你肯定应该寻找其他解决方案——正如我已经提到的,你需要AJAX轮询。如果我使用AJAX轮询,我不太确定是否会出现性能问题。因为我在同一时间拥有1000多名活跃用户。你觉得怎么样?这要看情况。如果你每秒打10次电话,这可能是个问题。如果你每5秒钟打一次电话,这不会是问题。您也可以查看Silverlight。我对异步轮询做了一些研究,发现了wcf的长轮询。我不太确定它是否适合我的问题。关于你对silverlight的建议,我目前还不知道。我是否必须在客户端计算机上安装任何程序/组件才能使用该技术?顺便说一句,我会试试你的建议。再次感谢你。
    public partial class _Default : System.Web.UI.Page, AlertServiceCallback
    {
        private AlertServiceClient _client;
        private Guid _guid = Guid.NewGuid();
    
        protected void Page_Load(object sender, EventArgs e)
        {
            InstanceContext context = new InstanceContext(this);
            _client = new AlertServiceClient(context);
            _client.RegisterClient(_guid);
        }
    
        protected void btnGetClients_Click(object sender, EventArgs e)
        {
            //Try to retrive all active clients
            Client[] cs = _client.GetAllClients(_guid);
            List<Client> list = new List<Client>(cs);
            //Bind to dropDownList to display all active clients
            ddlClients.DataSource = list;
            ddlClients.DataBind();
        }
    
        #region "CallBack"
    
        public void OnRegister(string message)
        {
            throw new NotImplementedException();
        }
    
        public void OnMessageSending(string message)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    
    }
    
    [ServiceContract(Name = "AlertService",Namespace = "http://www.testWcf.com/",
    CallbackContract = typeof(IAlertCallBack),SessionMode = SessionMode.Required)]
    public interface IAlertService
    {       
        [OperationContract(IsOneWay = true)]
        void RegisterClient(Guid id, string name);
    
        [OperationContract(IsOneWay = false)]
        List<Client> GetAllClients(Guid id);
    
        [OperationContract(IsOneWay = true)]
        void SendMessage(Guid fromId, Guid toId, string message);
    }
    
    public interface IAlertCallBack
    {
        [OperationContract(IsOneWay = true)]
        void OnRegister(string message);
    
        [OperationContract(IsOneWay = true)]
        void OnMessageSending(string message);
    }
    
    
    public class AlertService : IAlertService
    {
    
        private object locker = new object();
    
        private Dictionary<Client, IAlertCallBack> clients = new Dictionary<Client, IAlertCallBack>();
    
        public AlertService() { }
    
        public void RegisterClient(Guid guid)
        {
            IAlertCallBack callback = OperationContext.Current.GetCallbackChannel<IAlertCallBack>();
    
            //---prevent multiple clients adding at the same time---
            lock (locker)
            {
                clients.Add(new Client { Id = guid, Name = name }, callback);
            }
    
        }
    
        public List<Client> GetAllClients(Guid guid)
        {
            //---get all the clients in dictionary---
            return (from c in clients
                    where c.Key.Id != guid
                    select c.Key).ToList();
        }
    
        ...
    }