我正在開發一個項目,並且變得有點卡住了。我正在創建一個客戶端服務器應用程序,它允許客戶端訂閱服務器以將消息轉發給它。WCF發佈/訂閱並使用回調向特定用戶發送數據
我遇到的問題是,當客戶訂閱我希望他們只接收與他們有關的更新。系統基本上傳遞來自服務器監控的SQL服務器DB的消息。當收到新消息時,服務器應該僅根據客戶端計算機上登錄的用戶將消息轉發給應用的客戶端。
我看了一下,發現了代碼示例,它們註冊了所有已訂閱的客戶端的消息,但沒有顯示如何識別單個客戶端以及消息是否適用於他們。
如果有人可以幫助或指出我在正確的方向,它將不勝感激。
編輯只是爲了更清晰,我沒有那麼多不知道如何操作回調和訂閱,但如何操作當用戶訂閱,他們可以與回調信息一起提供有用戶ID的訂閱服務,它可以然後用於識別哪些特定用戶需要發送消息。
現在,您可以找一些我下面的代碼:
namespace AnnouncementServiceLibrary
{
[ServiceContract(CallbackContract = typeof(IMessageCallback))]
public interface IMessageCheck
{
[OperationContract]
void MessageCheck();
}
}
namespace AnnouncementServiceLibrary
{
public interface IMessageCallback
{
[OperationContract(IsOneWay = true)]
void OnNewMessage(Mess message);
}
}
訂閱/退訂:
private static readonly List<IMessageCallback> subscribers = new List<IMessageCallback>();
public bool Subscribe()
{
try
{
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
//If they dont already exist in the subscribers list, adds them to it
if (!subscribers.Contains(callback))
subscribers.Add(callback);
return true;
}
catch
{
//Otherwise if an error occurs returns false
return false;
}
}
/// <summary>
/// Unsubscribes the user from recieving new messages when they become avaliable
/// </summary>
/// <returns>Returns a bool that indicates whether the operation worked or not</returns>
public bool Unsubscribe()
{
try
{
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
//If they exist in the list of subscribers they are then removed
if (subscribers.Contains(callback))
subscribers.Remove(callback);
return true;
}
catch
{
//Otherwise if an error occurs returns false
return false;
}
}
這最後的時刻isnt't作爲基本工作當用戶訂閱,因爲它循環通過我希望它過濾基於用戶userID的LINQ查詢:
#region IMessageCheck Members
/// <summary>
/// This method checks for new messages recieved based on those who have subscribed for the service
/// </summary>
public void MessageCheck()
{
//A continuous loop to keep the method going
while(true)
{
//Changes the thread to a sleep state for 2 mins?
Thread.Sleep(200000);
//Go through each subscriber based on there callback information
subscribers.ForEach(delegate(IMessageCallback callback)
{
//Checks if the person who wanted the callback can still be communicated with
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
//Creates a link to the database and gets the required information
List<Mess> mess = new List<Mess>();
List<Message> me;
List<MessageLink> messLink;
AnnouncementDBDataContext aDb = new AnnouncementDBDataContext();
me = aDb.Messages.ToList();
messLink = aDb.MessageLinks.ToList();
//Query to retrieve any messages which are newer than the time when the last cycle finished
var result = (from a in messLink
join b in me
on a.UniqueID equals b.UniqueID
where b.TimeRecieved > _time
select new { b.UniqueID, b.Author, b.Title, b.Body, b.Priority, a.Read, b.TimeRecieved });
//Foreach result a new message is created and returned to the PC that subscribed
foreach (var a in result)
{
Mess message = new Mess(a.UniqueID, a.Author, a.Title, a.Body, a.Priority, (bool)a.Read, a.TimeRecieved);
callback.OnNewMessage(message);
}
}
//If the requesting PC can't be contacted they are removed from the subscribers list
else
{
subscribers.Remove(callback);
}
});
//Sets the datetime so the next cycle can measure against to see if new messages have been recieved
_time = DateTime.Now;
}
}
#endregion
非常感謝您的想法,閱讀您的文章,它適合我期待這樣做,謝謝。 – manemawanna 2010-05-27 08:20:58