[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] public class ChatService : IChat { Dictionary<Client, IChatCallback> clients = new Dictionary<Client, IChatCallback>(); List<Client> clientList = new List<Client>(); public IChatCallback CurrentCallback { get { return OperationContext.Current.GetCallbackChannel<IChatCallback>(); } } object syncObj = new object(); private bool SearchClientsByName(string name) { foreach (Client c in clients.Keys) { if (c.Name == name) { return true; } } return false; } #region IServices Members // Public client connection // retern true, when the connection has been established successfully // otherwise return false public bool Connect(Client client) { lock (syncObj) { // Remove the client if it exists RemoveSubscriberByKey(client); // Add client with the callback AddSubscriber(client); OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted); OperationContext.Current.Channel.Closed += new EventHandler(Channel_Closed); foreach (IChatCallback callback in clients.Values) { try { if (((ICommunicationObject)callback).State == CommunicationState.Opened) { // State is still opened, but actully is not CallMethod(() => callback.RefreshClients(clientList)); CallMethod(() => callback.UserJoin(client)); } else { RemoveSubscriberByValue(callback); } } catch { RemoveSubscriberByValue(callback); return false; } } } return true; } private void AddSubscriber(Client client) { clients.Add(client, CurrentCallback); clientList.Add(client); } private void RemoveSubscriber(Client client) { clients.Remove(client); clientList.Remove(client); } private void RemoveSubscriberByKey(Client client) { if (clients.Count > 0) { foreach (var item in clients.Keys.Where(item => item.Name.Equals(client.Name))) { clients.Remove(client); clientList.Remove(client); } } } private void RemoveSubscriberByValue(IChatCallback callback) { if(clients.Values.Contains(callback)) { Client c = clients.FirstOrDefault(x => x.Value == callback).Key; clients.Remove(c); clientList.Remove(c); } } void Channel_Closed(object sender, EventArgs e) { IChatCallback machine = sender as IChatCallback; RemoveSubscriberByValue(machine); } void Channel_Faulted(object sender, EventArgs e) { IChatCallback machine = sender as IChatCallback; RemoveSubscriberByValue(machine); } public void CallMethod(Action methodToBeCalled) { try { methodToBeCalled(); } catch (TimeoutException ex) { } catch (CommunicationException ex) { } catch (ObjectDisposedException ex) { } catch (Exception ex) { } } }
var
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)