使用WCF回调和asp.net实现发布/订阅模式的问题 [英] problem with using WCF Callback and asp.net to implement publish/subscribe pattern
问题描述
这是我的第一个web应用程序与wcf。所以请指导我作为一个新的家伙。
我试图使用WCF回调来实现发布/订阅模式。我想将消息从UserA发送到UserB或UserA到每个客户端。我有一个来自这里的示例
在我的应用程序中,我使用asp.net作为客户端连接wcf服务,而我发现一个问题,当我订阅wcf服务。
wcf服务不包含任何其他客户端对象。所以当我调用GetAllClients(_guid),它将只返回一个客户端本身。
这里是asp.net页面的代码(我把每个控件内部updatePanel )
public partial class _Default:System.Web.UI.Page,AlertServiceCallback
{
private AlertServiceClient _客户;
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)
{
//尝试退出所有活动客户端
Client [] cs = _client .GetAllClients(_guid);
List< Client> list = new List< Client>(cs);
//绑定到dropDownList以显示所有活动的客户端
ddlClients.DataSource = list;
ddlClients.DataBind();
}
#regionCallBack
public void OnRegister(string message)
{
throw new NotImplementedException();
}
public void OnMessageSending(string message)
{
throw new NotImplementedException();
}
#endregion
}
这里是WCF上的IService和服务。
[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();
私人字典< Client,IAlertCallBack> clients = new Dictionary< Client,IAlertCallBack>();
public AlertService(){}
public void RegisterClient(Guid guid)
{
IAlertCallBack callback = OperationContext.Current.GetCallbackChannel< IAlertCallBack> );
// ---防止多个客户端同时添加---
lock(locker)
{
clients.Add(new Client {Id = guid,Name = name},callback);
}
}
public List< Client> GetAllClients(Guid guid)
{
// ---获取字典中的所有客户端 -
return(from c in clients
其中c.Key.Id!= guid
选择c.Key).ToList();
}
...
}
问题是:
-
是否可以使用asp.net和wcf回调实现这个发布/ (我已经尝试了窗口应用程序,它工作正常)
-
如果可能,如何保持所有客户端连接到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 clients 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 subscrib 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:
Is it possible to implement this publish/subscribe with asp.net and wcf callback? (I already tried on window app and it worked fine)
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屋!