Costruire una chat per Silverlight con il PollingDuplexHttpBinding
di Cristian Civera, in Windows Communication Foundation, 16 giugno 2009
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.
Attenzione: Questo articolo contiene un allegato
Contenuti dell'articolo
- Pagina 1
- Pagina 2
- Pagina 3
- Pagina 4
- Pagina 5
- Pagina 6
Sullo stesso argomento
-
Mostrare le camere di sorveglianza tramite il .NET Micro Framework
-
La piattaforma Microsoft per il cloud computing: Windows Azure
-
Interoperabilità con WCF: invocare servizi da PHP e Flash
-
Le novità di Windows 7 per gli sviluppatori
-
Le problematiche più comuni di un'architettura M-V-VM con WPF
-
Introduzione a .NET RIA Services
-
Architettura Model-View-ViewModel in un'applicazione WPF
-
Condizioni e regole in Windows Workflow Foundation
-
Utilizzare Message Queuing per scalare le applicazioni

















Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.