In precedenti script si è già visto come utilizzare un web service e come sia abbastanza semplice farlo con gli strumenti messi a disposizione dal .NET Framework.
Il web service in questione è offerto da Tiscali e fa parte di una serie di servizi per webmaster lanciati da poco.
La lista è visibile all'indirizzo http://webservices.tiscali.com
Non tutti sanno che è possibile invocare un web service in modalità asincrona, ovvero richiamare lo stesso senza attendere che l'esecuzione sia terminata.
In questo esempio faremo proprio uso di questo concetto.
Innanzitutto creiamo il codice per l'inserimento del numero di telefono, prefisso e messaggio:
<p><b>Invia un SMS con Tiscali</b></p> <asp:PlaceHolder id="sendSmsZone" runat="server"> <form runat="server"> <i>Prefisso:</i> <select size="1" cols="1" id="prefisso" runat="server">
[..]
</select> <i> Numero</i><input type="text" id="numero" cols="10" maxlength="7" runat="server"/> <br><i>Messaggio:</i><br> <textarea rows="5" cols="30" id="messaggio" runat="server"/> <br><input type="submit" OnServerClick="sendsms_click" runat="server" value="Invia SMS"/> </form> </asp:PlaceHolder>
I metodi più usati per la visualizzazione di un messaggio d'attesa sono:
- l'utilizzo di DHTML, facendo comparire all'invio del form un layer che precedentemente era nascosto;
- la restituzione all'utente di codice HTML dopo l'invio del form che mostra un messaggio d'attesa, con un successivo postback della pagina.
Il primo non funziona su tutti i browsers, il secondo mostra un messaggio d'attesa indicante l'operazione in corso quando in realtà l'operazione non è ancora partita. Partirà al secondo postback. Questo porta ad un spreco di secondi per l'utente.
Ecco come risolviamo noi il problema:
- inviamo il form al server;
- avviamo l'operazione in modalità asincrona, restituendo immediatamente un messaggio di attesa;
- effettuaiamo un secondo postback dopo un paio di secondi per controllare sul server che l'operazione sia terminata;
- avvisiamo l'utente dell'esito dell'operazione.
Ecco il codice:
private void sendsms_click(object s, EventArgs e)
{
//nascondo l'area per l'invio
sendSmsZone.Visible=false;
//mostro il messaggio d'attesa
risposta.Visible=true;
risposta.InnerHtml="
Attendere, invio in corso...
";//mostro il meta tag per il refresh
refresh.Visible=true;
sendSmsInvoker sms=new sendSmsInvoker(startSendSms);
//memorizzo nella session il riferimento alla chiamata asincrona
//quando parte il nuovo thread
Session["sms"]=sms.BeginInvoke(new AsyncCallback(sendSmsCallback),sms);
}
private delegate void sendSmsInvoker();
private void startSendSms()
{
//formatto il numero
string pNumber="+39"+prefisso.Value+numero.Value;
TiscaliSMSServices sms=new TiscaliSMSServices();
//invio l'sms
SendSMSResult answer=sms.SendFreeSMS(pNumber, messaggio.Value);
//memorizzo il risultato nella sessione
Session["answer"]=answer;
}
private void sendSmsCallback(IAsyncResult ar)
{
//termino la chiamata
sendSmsInvoker sms=(sendSmsInvoker)ar.AsyncState;
sms.EndInvoke(ar);
}
private void Page_Load(object s, EventArgs e)
{
Response.Expires=0;
//partito il refresh e devo mostrare la risposta
if (Request.QueryString["wait"]!=null)
{
//attendo che la chiamata termini
//se è già terminata prosegue subito
IAsyncResult ar=(IAsyncResult)Session["sms"];
ar.AsynWaitHandle.WaitOne(60000,true);
//recupero il risultato memorizzato
SendSMSResult answer=(SendSMSResult)Session["answer"];
//azzero, non mi servono più
Session.Remove("sms");
Session.Remove("answer");
//controllo il risultato
string msg="";
if (answer==null)
msg="Errore durante l'invio del messaggio";
else if (answer.Error!=null && answer.Error.Trim()!="")
msg=answer.Error;
else if (answer.SmsSentId!=null)
msg="Messaggio inviato. Id: "+answer.SmsSentId;
//mostro la rispota
risposta.Visible=true;
sendSmsZone.Visible=false;
risposta.InnerHtml="
"+msg+"
";}
}
In pratica, effettuo una chiamata asincrona ad una sub. Questa invia l'sms, riceve il risultato e lo memorizza in una variabile di sessione. In un'altra variabile di sessione manteniamo il riferimento alla chiamata asincrona, in modo di attendere il suo termine, mediante l'uso del metodo WaitOne.
Questo metodo, blocca il thread corrente, di conseguenza il browser che attende la risposta del server mantiene mostrato il messaggio d'attesa finché il thread non sarà terminato (questo perché abbiamo il buffer abilitato).
Il risultato è molto piacevole, non inganna l'utente e soprattutto questa tecnica può essere usata anche in altri ambiti, come nel caso di ricerca o di esecuzione di operazioni molto lunghe.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.