Это мое первое веб-приложение с WCF. Поэтому, пожалуйста, ведите меня как новый парень.
Я пытаюсь использовать функцию обратного вызова WCF для реализации шаблона публикации / подписки. Я хотел бы отправить сообщение от UserA к UserB или UserA каждому клиенту в данный момент. Я получил пример от здесь .
В своем приложении я использую ASP.NET в качестве клиента для подключения службы WCF, и обнаружил проблему при подписке на службу WCF.
Служба WCF не содержит никаких других объектов клиентов. Поэтому, когда я звоню GetAllClients(_guid)
, он вернет только 1 клиента, который сам по себе.
Вот код на странице ASP.NET (я помещаю каждый элемент управления внутрь 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
}
Здесь указаны IService
и Service
на WCF соответственно.
[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();
}
...
}
Вопросы:
Можно ли реализовать эту публикацию / подписку с помощью обратного вызова ASP.NET и WCF? (Я уже пробовал на оконном приложении, и он работал нормально)
Если это возможно, как я могу сохранить все клиенты, которые подключаются к службе WCF, чтобы я мог использовать эти GuId для вызова метода обратного вызова.
Спасибо.