Un numéro offert




Recherche :

Interaction Silverlight coté client et php coté serveur

Silverlight permet de créer des applications web à moindre coût.

Visual Web Developer 2010 Express est gratuit en téléchargement.
Version française : http://www.microsoft.com/express/downloads/


Le “Tools Kit” Silverlight :
Version française : http://www.microsoft.com/downloads/details.aspx?familyid=EFF8A0DA-0A4D-48E8-8366-6DDF2ECAD801&displaylang=fr

Une application Silverlight s'exécute coté client bien entendu. (Win et Mac)
Elle sera hébergée sur un serveur LAMP.
Pour faire communiquer plusieurs clients Silverlight entre eux nous utiliserons le protocole HTTP + deux scripts PHP.
Un script pour écrire les messages et un autre pour les lire.

Pour illustrer ce principe voilà donc un chat Silverlight + PHP léger.

L'application sera écrite en Visual Basic.

Le nom de l'application : ChatSL2phpVB

1. Description de l’application

L'interface sera constituée des éléments suivants :
- TextBox pour inscrire son Pseudo
- TextBox pour saisir les messages
- ScrollViewer pour afficher les messages

Un aperçu de l'interface :

2. Principe général

On utilisera l'objet WebClient pour la communication HTTP

Ecriture d'un message :
Client SL -> WebClient -> POST "data" -> write_msg.php : écriture dans un dossier "/msg" d'un fichier référencé temporellement (timestamped) sur le serveur
Retour HTTP : 0

Relever un message :
Client SL -> WebClient -> read_msg.php : lecture de tous les fichiers "timestamped"
Retour HTTP : fichier si non encore lu ou nothing

Le Script write_msg.php :

<?php
if (isset($_POST["user"]))
{
    list($usec, $sec) = explode(" ", microtime());
    $ts = $sec.substr($usec,2,4);
    // On crée le fichier message dans le dossier msg
    $fichier = fopen('msg/'.$ts, 'w+');
    fwrite($fichier, stripslashes($_POST['data']));
    fclose($fichier);
    echo "0";
    $dossier = opendir('msg');
    while ($fichier = readdir($dossier))
    {
        if (!preg_match("#^[.]{1,2}[a-z0-9 -.]*#i",$fichier))
        {
            // On en profite pour purger les msg plus vieux que 15 secondes
            if ($fichier < ($ts - 150000))
            {
                unlink('msg/'.$fichier);
            }
        }
    }
    closedir($dossier);
}
?>

Le script read_msg.php :

<?php
session_start();
// ouvrir le dosssier msg
$dossier = opendir('msg');
 
while ($fichier = readdir($dossier))
{
    if (!preg_match("#^[.]{1,2}[a-z0-9 -.]*#i",$fichier))    
    {
        $files_array[] = $fichier;      
    }
}
closedir($dossier);
 
sort($files_array);
 
foreach ($files_array as $key => $val)
{
   if ($_SESSION['last_msg_ts'] < $val)
   {
        // Lit le message non lu
        readfile('msg/'.$val,'r');
        // Indique le dernier message lu
        $_SESSION['last_msg_ts'] = $val;
        exit;       
   }
}
?>

3. Poster un message avec WebClient

Les données sont envoyées de manière asynchrone avec une requête POST.
Suite à l'appui du bouton Send :
- Stop à la réception des messages
- Transmission au script write_msg.php les paramètres "user" et "data".
- Attente du retour serveur de la valeur "0", puis relance de la réception des messages.
Coté serveur :
- écriture du fichier référencé temporellement par rapport à l'heure du serveur
- vérification des vieux messages présents dans le dossier '/msg'.
- S'il sont plus vieux de 15 secondes on les supprime.

Private Sub SendMsg(ByVal Data As String)
 
        ReadMsgTmr.Stop()
 
        Try
            Dim Client As New WebClient()
            Client.Headers("Content-Type") = "application/x-www-form-urlencoded"
            AddHandler Client.UploadStringCompleted, AddressOf SendMsgCompleted
            Client.UploadStringAsync(New Uri(String.Format("{0}/write_msg.php",
            BASEPATH)),    "Post", "user=" & UsrTbx.Text & "&data=" & Data)
 
        Catch ex As Exception
 
        End Try
 
 
    End Sub
 
    Private Sub SendMsgCompleted(ByVal sender As Object, _
                                 ByVal e As UploadStringCompletedEventArgs)
 
        Try
            Dim Msg As String = e.Result
            Select Case Msg
                Case Nothing
                    ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1)
                    ReadMsgTmr.Start()
                    Exit Sub
                Case "0"
                    ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1)
                    ReadMsgTmr.Start()
            End Select
        Catch ex As Exception
 
        End Try
 
    End Sub

4. Lire un message avec WebClient

Le relevé des messages est fait de façon périodique selon la logique suivante :
Mode "Idle" :
- Toute les 1,5 seconde
Mode "Rafale" :
- Toute les 0,15 seconde
Mode "After Writing" :
- Aussitot après avoir posté un message

Nota : on aurait pu imaginer un "LongIdle" de 3 secondes pour les périodes d'inactivité ... longue.

    Private Sub ReadMsgTmr_Tick(ByVal sender As Object, _
                                ByVal e As System.EventArgs) Handles ReadMsgTmr.Tick
 
        ReadMsgTmr.Stop()
 
        Try
 
            Dim Client = New WebClient
            AddHandler Client.DownloadStringCompleted, AddressOf ReadMsgComplete
            Client.DownloadStringAsync(New Uri(Config.BASEPATH & "/read_msg.php", UriKind.Absolute), 0)
 
            Client = Nothing
 
        Catch ex As Exception
            'HtmlPage.Window.Alert(ex.Message)
        End Try
 
    End Sub
 
    Private Sub ReadMsgComplete(ByVal sender As Object, _
                                ByVal e As DownloadStringCompletedEventArgs)
        Try
            ' Si il y a un message
            Dim Msg As String = e.Result
            If Msg <> "" Then DisplayTextinChatBox(Msg)
                ' raffale
                ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(150)
            Else
                ' idle
                ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1500)
            End If
 
        Catch ex As Exception
 
        End Try
        ReadMsgTmr.Start()
 
    End Sub

5. Déployer

Un simple copier coller des fichiers via ftp, on change le CHMOD du dossier "msg" à 777 et voilà :)

6. Annexes

Le code VB complet :

Imports System.IO.IsolatedStorage
Imports System.Windows.Threading
 
Partial Public Class MainPage
    Inherits UserControl
    Private AppSetting As IsolatedStorageSettings = IsolatedStorageSettings.ApplicationSettings
    Private WithEvents ReadMsgTmr As New DispatcherTimer
    Private Smoke As Boolean
    Private BASEPATH As String = "" ' "http://www.monsite.fr/MiniChat" 'Test path
    Private Client As New WebClient
 
    Public Sub New()
        InitializeComponent()
        AddHandler Client.DownloadStringCompleted, AddressOf ReadMsgComplete
        ReadMsgTmr.Interval = TimeSpan.FromMilliseconds(1500)
        If AppSetting.Keys.Count > 0 Then
            For Each Key In AppSetting.Keys
                Select Case Key.ToString
                    Case "UserName"
                        If AppSetting("UserName").ToString <> "" Then
                            UsrTbx.Text = AppSetting("UserName").ToString
                        End If
                End Select
            Next
        End If
        MsgTbx.Focus()
        ReadMsgTmr.Start()
 
        'Dim Src As System.Uri = Application.Current.Host.Source
        If BASEPATH = "" Then
            Dim uri As String = Application.Current.Host.Source.AbsoluteUri
            uri = uri.Substring(0, uri.IndexOf("/ChatSL2phpVB.xap"))
            BASEPATH = uri ' : SendMsg(uri)
            'supprimez la ligne ci dessous pour compiler une version déployable
            BASEPATH = "http://www.furukoo.fr/MiniChat"
        End If
 
    End Sub
 
    Public Sub DisplayTextinChatBox(ByVal Msg As String)
 
        If Msg Is Nothing Then Exit Sub
        '' Crée un TextBlock
        Dim Tbl As New TextBox
        With Tbl
            .Text = Msg
            .TextWrapping = TextWrapping.Wrap
            .IsReadOnly = True
            .Style = DirectCast(Me.Resources("ChatStyle"), Windows.Style)
            If Smoke Then
                .Background = New SolidColorBrush(Color.FromArgb(255, 248, 248, 248))
                Smoke = False
            Else
                Smoke = True
            End If
        End With
 
        With MsgSpl.Children
            '' Limite le nombre de messages dans la ListBox
            If .Count > 50 Then .RemoveAt(50)
            .Insert(0, Tbl)
        End With
 
        ' Déplace l'ascenseur vers le haut
        MsgSvr.ScrollToVerticalOffset(0)
 
    End Sub
 
    Private Sub SendMsg(ByVal Data As String)
 
        ReadMsgTmr.Stop()
 
        Try
            Dim Client As New WebClient()
            Client.Headers("Content-Type") = "application/x-www-form-urlencoded"
            AddHandler Client.UploadStringCompleted, AddressOf SendMsgCompleted
            Client.UploadStringAsync(New Uri(String.Format("{0}/write_msg.php", BASEPATH)), _
                                     "Post", _
                                     "user=" & UsrTbx.Text & "&data=" & Data)
 
        Catch ex As Exception
 
        End Try
 
    End Sub
 
    Private Sub SendMsgCompleted(ByVal sender As Object, _
                                 ByVal e As UploadStringCompletedEventArgs)
 
        Try
            Dim Msg As String = e.Result
            Select Case Msg
                Case Nothing
                    ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1)
                    ReadMsgTmr.Start()
                    Exit Sub
                Case "0"
                    ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1)
                    ReadMsgTmr.Start()
            End Select
        Catch ex As Exception
 
        End Try
 
    End Sub
 
    Private Sub ReadMsgTmr_Tick(ByVal sender As Object, _
                                ByVal e As System.EventArgs) Handles ReadMsgTmr.Tick
 
        ReadMsgTmr.Stop()
 
        Try
 
            Client.DownloadStringAsync(New Uri(BASEPATH & "/read_msg.php", UriKind.Absolute), 0)
 
        Catch ex As Exception
            'HtmlPage.Window.Alert(ex.Message)
        End Try
 
    End Sub
 
    Private Sub ReadMsgComplete(ByVal sender As Object, _
                                ByVal e As DownloadStringCompletedEventArgs)
        Try
            ' Si il y a un message
            Dim Msg As String = e.Result
            If Msg <> "" Then
                DisplayTextinChatBox(Msg)
                ' raffale
                ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(150)
            Else
                ' idle
                ReadMsgTmr.Interval = System.TimeSpan.FromMilliseconds(1500)
            End If
 
        Catch ex As Exception
 
        End Try
        ReadMsgTmr.Start()
 
    End Sub
 
    Private Sub MsgTbx_GotFocus(ByVal sender As Object, _
                                ByVal e As System.Windows.RoutedEventArgs) Handles MsgTbx.GotFocus
        MsgTbx.Text = ""
        MsgTbx.Focus()
 
    End Sub
 
    Private Sub MsgTbx_KeyUp(ByVal sender As System.Object, _
                             ByVal e As System.Windows.Input.KeyEventArgs) Handles MsgTbx.KeyUp
        Select Case e.Key
            Case Key.Enter
                If MsgTbx.Text = "" Then MsgTbx.Focus() : Exit Sub
                SendMsg(UsrTbx.Text & " : " & MsgTbx.Text)
                MsgTbx.Text = ""
                MsgTbx.Focus()
            Case Else
                Exit Sub
        End Select
    End Sub
 
    Private Sub UsrTbx_TextChanged(ByVal sender As Object, _
                                   ByVal e As System.Windows.Controls.TextChangedEventArgs) _
                                   Handles UsrTbx.TextChanged
 
        AppSetting("UserName") = UsrTbx.Text
        AppSetting.Save()
 
    End Sub
 
End Class

7. Testez en direct

Vous pouvez tester ce Mini Chat ici

Les sources disponible ici

Proposer un tutoriel
Vous souhaitez partagez vos connaissances avec les membres de Programmez! Publiez vos tutoriels.

L'auteur
Navedac (Yvan Nébotieff)


http://www.furukoo.fr

De A à Z
Programmez.com - 2013 - Tous droits réservés
Développement - WEB - ASP - PHP - C++ - Delphi - Java - Magazines - Ressources - Forum - Télécharger - Video - Emploi - Campus - .Net - Tutoriels

Le présent site Web est édité par Go 02, Sarl inscrite au RCS de Paris sous le N° 411321366 et dont le siège social est au 21 rue de Fécamp 75012 Paris.
Adresse de courrier électronique :diff@programmez.com

Le directeur de la publication du site www.programmez.com est Jean-Claude Vaudecrane en qualité de gérant de la sarl GO 02

Le portail du décideur informatique en entreprise : Solutions & Logiciels