Я сейчас работаю над проектом и немного застрял. Я создаю клиент-серверное приложение, которое позволяет клиенту подписываться на сервер, чтобы ему пересылались сообщения.
Проблема, с которой я сталкиваюсь, заключается в том, что, когда клиент подписывается, я хочу, чтобы он получал только те обновления, которые относятся к ним. Система в основном передает сообщения от БД SQL-сервера, которые контролирует сервер. При получении нового сообщения сервер должен пересылать сообщение только тем клиентам, к которым оно применяется, в зависимости от того, кто вошел на клиентский компьютер.
Я посмотрел и нашел примеры кода, которые регистрируют сообщения для рассылки всем подписавшимся клиентам, но не те, которые показывают, как идентифицировать отдельных клиентов и применяются ли к ним сообщения.
Если кто-нибудь может помочь или указать мне правильное направление, это будет оценено.
edit Просто, чтобы быть более понятным, я не столько удивляюсь, как управлять обратными вызовами и подпиской, но как управлять службой подписки, где, когда пользователь подписывается, они могут предоставить свой идентификатор пользователя вместе с информацией обратного вызова , который затем можно использовать для определения того, каким конкретным пользователям необходимо отправлять сообщения.
Теперь вы можете найти мой код ниже:
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;
}
}
Наконец, на данный момент это не работает, так как в основном, когда пользователь подписывается, когда он проходит через него, я хочу, чтобы он фильтровал запрос LINQ на основе идентификатора пользователя user:
#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