使用WCF回调和asp.net来实现发布/订阅模式 [英] using WCF Callback and asp.net to implement publish/subscribe pattern

查看:46
本文介绍了使用WCF回调和asp.net来实现发布/订阅模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我使用WCF的第一个Web应用程序。因此,请以新手身份指导我。



我正在尝试使用WCF回调实现发布/订阅模式。我现在想将消息从UserA发送到UserB或将UserA发送给每个客户端。我从此处



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



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



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

 公共局部类_Default:System.Web.UI.Page,AlertServiceCallback 
{
private AlertServiceClient _client;
私人Guid _guid = Guid.NewGuid();

受保护的无效Page_Load(对象发送者,EventArgs e)
{
InstanceContext context = new InstanceContext(this);
_client = new AlertServiceClient(context);
_client.RegisterClient(_guid);
}

保护无效btnGetClients_Click(对象发送者,EventArgs e)
{
//尝试检索所有活动的客户端
Client [] cs = _client .GetAllClients(_guid);
List< Client> list =新的List< Client>(cs);
//绑定到dropDownList以显示所有活动客户端
ddlClients.DataSource = list;
ddlClients.DataBind();
}

#region CallBack

public void OnRegister(string message)
{
throw new NotImplementedException();
}

public void OnMessageSending(string message)
{
throw new NotImplementedException();
}

#endregion

}

分别是WCF上的 IService Service

  [ServiceContract(Name = AlertService,Namespace = http://www.testWcf.com/,
CallbackContract = typeof(IAlertCallBack),SessionMode = SessionMode.Required)]
公共接口IAlertService
{
[OperationContract(IsOneWay = true)]
void RegisterClient(Guid id,string name);

[OperationContract(IsOneWay = false)]
List< Client> GetAllClients(向导ID);

[OperationContract(IsOneWay = true)]
void SendMessage(Guid fromId,Guid toId,string message);
}

公共接口IAlertCallBack
{
[OperationContract(IsOneWay = true)]
void OnRegister(string message);

[OperationContract(IsOneWay = true)]
void OnMessageSending(string message);
}


公共类AlertService:IAlertService
{

私人对象储物柜= new object();

专用Dictionary< Client,IAlertCallBack>客户=新的Dictionary< Client,IAlertCallBack>();

public AlertService(){}

public void RegisterClient(Guid guid)
{
IAlertCallBack callback = OperationContext.Current.GetCallbackChannel< IAlertCallBack>( );

//-防止同时添加多个客户端-
锁(储物柜)
{
client.Add(new Client {ID = guid,Name = name},callback);
}

}

公共列表<客户> GetAllClients(Guid guid)
{
// ---获取字典中的所有客户端---
return(从c到
的客户端中,其中c.Key.Id!= guid
选择c.Key).ToList();
}

...
}

问题是:


  1. 是否可以使用ASP.NET和WCF回调实现此发布/订阅? (我已经在window app上尝试过,并且工作正常)


  2. 如果可能的话,如何保留所有连接到WCF服务的客户端,以便使用这些GuId调用回调方法。


谢谢。

解决方案

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



您不能在ASP.NET应用程序中使用WCF回调。它无法工作,因为页面仅用于服务单个HTTP请求-这意味着页面很可能仅存在几分之一秒,因此您的注册也是如此。即使您能够获得客户列表,也将无法调用 OnRegister OnMessageSending ,因为在那里



即使您在请求处理后强制代理有效,它仍只会通知后面的代码,而不通知您在客户端浏览器中呈现的页面。 / p>

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



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


This is my first web application with WCF. So please guide me as a new guy.

I'm trying to use WCF Callback to implement publish/subscribe pattern. I would like to send the message from UserA to UserB or UserA to every client at the moment. I got an example from here .

In my app, I use ASP.NET as a client to connect WCF service instead and I found a problem when I subscribe to WCF service.

The WCF service does not hold any other clients object. So when I call GetAllClients(_guid), it will return only 1 client which is itself.

Here is the code in ASP.NET page (I put every control inside updatePanel)

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

}

Here is the IService and Service on WCF respectively.

[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();
    }

    ...
}

Questions are:

  1. Is it possible to implement this publish/subscribe with ASP.NET and WCF callback? (I already tried on window app and it worked fine)

  2. If it is possible, how can I keep all clients that is connecting to WCF Service so I can use those GuId to call callback method.

Thank you.

解决方案

I don't know why you don't get list of clients - you should but there are much worse problems with your code.

You can't use WCF callback in ASP.NET application. It cannot work because page lives only to serve single HTTP request - it means it most probably lives only for fraction of second and so also your registration. Even If you will be able to get list of clients you will not be able to call OnRegister or OnMessageSending because there will be no proxy listening for these calls.

Even if you force proxy to live after request processing it will still notify only code behind, not your pages rendered in client browser.

Another problem is that it can work only with net.pipe or net.tcp binding. It will not work with wsDualHttp. It is very problematic to open multiple duplex clients from the same machine when using wsDualHttp.

You are doing it completely wrong. What you need is AJAX polling from client browser to asp.net which will call simple service in your chat system.

这篇关于使用WCF回调和asp.net来实现发布/订阅模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆