Costruire una chat per Silverlight con il PollingDuplexHttpBinding

6 pagine in totale: <<Indietro 1 2 [3] 4 5 6 Avanti >>

Implementazione del servizio

Definiti i contratti e le strutture dati, non resta che cominciare ad implementare il servizio WCF. Prima di tutto si definisce la classe facendo in modo, attraverso gli attributi ConcurrencyMode e InstanceContextMode, che questa sia istanziata una volta per ogni sessione, cioè per ogni utente della chat.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerSession)] 
public class ChatService : IChatService 
{ 
 
  private static ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim(); 
  private static Dictionary<String, IChatClient> users = new Dictionary<string, IChatClient>(); 
  private string userName; 
 
} 

Nell'esempio viene definita una variabile userName che mantiene l'utente della sessione rappresentata dall'istanza della classe, mentre attraverso il campo statico users si mantiene la lista degli utenti attualmente in chat. Data la possibilità di concorrenza, si sfrutta inoltre l'oggetto ReaderWriterLockSlim per effettuare lock differenziati in lettura e scrittura sul dictionary degli utenti. In alternativa si può utilizzare il generico e più semplice lock.

Le operazioni si assomigliano molto tra loro perciò si vede in questo articolo solo il metodo di SignIn, il resto è possibile vederlo dall'allegato. In questo metodo non si fa altro che ottenere dal Body il nome utente e ottenere tramite GetCallbackChannel il canale di comunicazione specifico per quell'utente per poi aggiungerlo alla lista degli utenti in chat. Il callback è di tipo IChatClient e questo permette, mantenendone un riferimento, di notificare tutte le operazioni che avvengono in chat a tutti gli utenti presenti.

public void SignIn(Message request) 
{ 
  // Ottengo il nome utente e lo salvo 
  string userName = request.GetBody<String>(); 
  this.userName = userName; 
 
  try 
  { 
    lockSlim.EnterWriteLock(); 
 
    // Ottengo il canale di comunicazione con il client 
    IChatClient channel = OperationContext.Current.GetCallbackChannel<IChatClient>(); 
    // Aggiungo alla lista degli utenti 
    users.Add(this.userName, channel); 
  } 
  finally 
  { 
    lockSlim.ExitWriteLock(); 
  } 
 
  ChatAction ca = new ChatAction 
  { 
    Action = "SignIn", 
    Data = userName 
  }; 
  // Notifico a tutti l'arrivo di un nuovo utente 
  SendActionToAll(ca); 
} 

La chiamata al metodo SendActionToAll permette di inviare la notifica di SignIn a tutte le sessioni così che possano mostrare il nuovo ingresso.

L'implementazione non fa altro che ciclare la collezione users e, ad ogni canale (ogni sessione utente), inviare il messaggio invocando NewAction.

private void SendActionToAll(ChatAction action) 
{ 
  try 
  { 
    lockSlim.EnterReadLock(); 
 
    // Per ogni sessione invio il messaggio 
    foreach (KeyValuePair<String, IChatClient> pair in users) 
    { 
      // Non posso usare lo stesso messaggio più di una volta 
      // Lo ricreo ogni volta 
      Message response = Message.CreateMessage(MessageVersion.Soap11, 
                                               "http://ws.winfxitalia.com/SL/Chat/NewAction", 
                                               action); 
 
      pair.Value.NewAction(response); 
    } 
 
  } 
  finally 
  { 
    lockSlim.ExitReadLock(); 
  } 
} 

Il binding apposito per Silverlight non fa altro che mantenere in coda il messaggio e rispondere con esso la successiva volta che il sistema di polling chiede al servizio se c'è qualcosa di nuovo.

6 pagine in totale: <<Indietro 1 2 [3] 4 5 6 Avanti >>

Attenzione: Questo articolo contiene un allegato

Contenuti dell'articolo

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

TUTORIALS
TOP TEN ARTICOLI
ARTICOLI VIA E-EMAIL

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

MEDIA
IN EVIDENZA
MISC