middleware/Communication/WSClient.cs
changeset 41 d2f735d7763f
equal deleted inserted replaced
40:0f31ebcc62b7 41:d2f735d7763f
       
     1 /*
       
     2 * This file is part of the TraKERS\Middleware package.
       
     3 *
       
     4 * (c) IRI <http://www.iri.centrepompidou.fr/>
       
     5 *
       
     6 * For the full copyright and license information, please view the LICENSE
       
     7 * file that was distributed with this source code.
       
     8 */
       
     9 
       
    10 /*
       
    11  * Projet : TraKERS
       
    12  * Module : MIDDLEWARE
       
    13  * Sous-Module : Communication
       
    14  * Classe : WSClient
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Reçoit des notifications du Front IDILL.
       
    19  * Interprète les positions des curseurs dans le temps à partir du top du front.
       
    20  * 
       
    21  * STATUS : EN DEVELOPPEMENT.
       
    22  * 
       
    23  */
       
    24 
       
    25 using System;
       
    26 using System.Collections.Generic;
       
    27 using System.Linq;
       
    28 using System.Text;
       
    29 using Fleck;
       
    30 using System.Threading;
       
    31 using System.Timers;
       
    32 using System.Windows.Media.Media3D;
       
    33 
       
    34 namespace Communication
       
    35 {
       
    36     public class WSClient
       
    37     {
       
    38         //Server WebSocket.
       
    39         WebSocketServer server;
       
    40         List<IWebSocketConnection> allSockets;
       
    41 
       
    42         //Permet de savoir si un curseur pour la main gauche/droite a été créé.
       
    43         private bool leftHandCursorCreated;
       
    44         private bool rightHandCursorCreated;
       
    45         private bool gesturesMessageCreated, modeMessageCreated;
       
    46         private bool gestureLocked, modLocked;
       
    47         //Intervalle minimum entre les gestures.
       
    48         private int timerElapsing;
       
    49         //Timers.
       
    50         private System.Timers.Timer _gesturesTimer;
       
    51         private System.Timers.Timer _userPositionTimer;
       
    52         //Dernier code envoyé.
       
    53         private String lastCode;
       
    54         //Messages envoyés en WS.
       
    55         private String rightHandMessage, leftHandMessage, gesturesMessage, modeMessage;
       
    56         //Messages précédents
       
    57         private String prevRightHandMessage, prevLeftHandMessage, prevGestureMessage, prevModeMessage;
       
    58 
       
    59         /*
       
    60         * Constructeur : On initialise le serveur avec une adresse et un port, au début les curseurs
       
    61         * ne sont pas créés et on indique au ThreadPool une fonction de callback de manière à vérifier
       
    62         * s'il reçoit des notifications.
       
    63         */
       
    64         public WSClient(String host, int port, int _timerElapsing)
       
    65         {
       
    66             FleckLog.Level = LogLevel.Debug;
       
    67             allSockets = new List<IWebSocketConnection>();
       
    68             server = new WebSocketServer(port, "ws://" + host + ":" + port);
       
    69 
       
    70             //Au départ, aucune main n'est dans le champ de recherche et aucune gesture n'est détectée.
       
    71             leftHandCursorCreated = false;
       
    72             rightHandCursorCreated = false;
       
    73             gesturesMessageCreated = false;
       
    74             modeMessageCreated = false;
       
    75             gestureLocked = false;
       
    76             modLocked = false;
       
    77             lastCode = "";
       
    78 
       
    79             timerElapsing = 500;// _timerElapsing;
       
    80 
       
    81             rightHandMessage = leftHandMessage = gesturesMessage = modeMessage = "";
       
    82 
       
    83             //On démarre le serveur WebSocket.
       
    84             server.Start(socket =>
       
    85             {
       
    86                 socket.OnOpen = () =>
       
    87                 {
       
    88                     Console.WriteLine("Open!");
       
    89                     allSockets.Add(socket);
       
    90                 };
       
    91                 socket.OnClose = () =>
       
    92                 {
       
    93                     Console.WriteLine("Close!");
       
    94                     allSockets.Remove(socket);
       
    95                 };
       
    96                 /*socket.OnMessage = message =>
       
    97                 {
       
    98                     Console.WriteLine(message);
       
    99                     allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
       
   100                 };*/
       
   101             });
       
   102 
       
   103             //On initialise le threadPool (appelé toutes les N ms).
       
   104             ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
       
   105 
       
   106             //On instancie le timer à N ms.
       
   107             _gesturesTimer = new System.Timers.Timer(timerElapsing);
       
   108             _userPositionTimer = new System.Timers.Timer(timerElapsing/5);
       
   109             //Dès que le timer est expiré, on appelle _timer_Elapsed.
       
   110             _gesturesTimer.Elapsed += new ElapsedEventHandler(_gesturesTimer_Elapsed);
       
   111             _userPositionTimer.Elapsed += new ElapsedEventHandler(_userPositionTimer_Elapsed);
       
   112 
       
   113             /*var input = Console.ReadLine();
       
   114             while (input != "exit")
       
   115             {
       
   116                 foreach (var socket in allSockets.ToList())
       
   117                 {
       
   118                     socket.Send(input);
       
   119                 }
       
   120                 input = Console.ReadLine();
       
   121             }*/
       
   122         }
       
   123 
       
   124         /*
       
   125          * Méthode appelée à l'expiration du timer pour les gestures et modes.
       
   126          */
       
   127         public void _gesturesTimer_Elapsed(object sender, ElapsedEventArgs e)
       
   128         {
       
   129             //On débloque la détection de gesture.
       
   130             gestureLocked = false;
       
   131             //On débloque la notification de nouveau mode.
       
   132             //modLocked = false;
       
   133             lastCode = "";
       
   134             //On arrête le timer.
       
   135             _gesturesTimer.Stop();
       
   136         }
       
   137 
       
   138         /*
       
   139          * Méthode appelée à l'expiration du timer pour les positions d'utilisateur.
       
   140          */
       
   141         public void _userPositionTimer_Elapsed(object sender, ElapsedEventArgs e)
       
   142         {
       
   143             //On débloque la détection de gesture.
       
   144             //gestureLocked = false;
       
   145             //On débloque la notification de nouveau mode.
       
   146             modLocked = false;
       
   147             lastCode = "";
       
   148             //On arrête le timer.
       
   149             _userPositionTimer.Stop();
       
   150         }
       
   151 
       
   152         /*
       
   153         * Méthode appelée lors d'une notification de type : main gauche entrée dans le champ.
       
   154         */
       
   155         public void LeftHandTracked(Point3D pt)
       
   156         {
       
   157             leftHandMessage = "0-" + pt.X + ";" + pt.Y + ";" + pt.Z;
       
   158             //Si le curseur de la main gauche n'est pas créé, alors on le crée.
       
   159             if (!leftHandCursorCreated)
       
   160                 leftHandCursorCreated = true;
       
   161         }
       
   162 
       
   163         /*
       
   164         * Méthode appelée lors d'une notification de type : main droite entrée dans le champ.
       
   165         */
       
   166         public void RightHandTracked(Point3D pt)
       
   167         {
       
   168             rightHandMessage = "1-" + pt.X + ";" + pt.Y + ";" + pt.Z;
       
   169             //Si le curseur de la main droite n'est pas créé, alors on le crée.
       
   170             if (!rightHandCursorCreated)
       
   171                 rightHandCursorCreated = true;
       
   172         }
       
   173 
       
   174         /*
       
   175         * Méthode appelée lors d'une notification de type : main gauche sortie du champ.
       
   176         */
       
   177         public void LeftHandQuit()
       
   178         {
       
   179             leftHandMessage = "";
       
   180             //Si le curseur de la main gauche existe, alors on le supprime.
       
   181             if (leftHandCursorCreated)
       
   182                 leftHandCursorCreated = false;
       
   183         }
       
   184 
       
   185         /*
       
   186         * Méthode appelée lors d'une notification de type : main droite sortie du champ.
       
   187         */
       
   188         public void RightHandQuit()
       
   189         {
       
   190             rightHandMessage = "";
       
   191             //Si le curseur de la main droite existe, alors on le supprime.
       
   192             if (rightHandCursorCreated)
       
   193                 rightHandCursorCreated = false;
       
   194         }
       
   195 
       
   196         /*
       
   197         * Méthode appelée lorsqu'une gesture a été détectée et que l'événement approprié a été lancé.
       
   198         */
       
   199         public void GesturePerformed(String code)
       
   200         {
       
   201             //Si le code vient d'être envoyé, on passe.
       
   202             /*if (lastCode.Equals(code))
       
   203                 return;
       
   204             lastCode = code;*/
       
   205             //Si une gesture a été effectuée, on bloque un certain temps.
       
   206             if (!gestureLocked)
       
   207             {
       
   208                 gestureLocked = true;
       
   209 
       
   210                 //On crée un message contenant le code à envoyer.
       
   211                 //if (!gesturesMessageCreated)
       
   212                 //{
       
   213                     gesturesMessageCreated = true;
       
   214                     gesturesMessage = "2-" + code;
       
   215 
       
   216                     //Console.WriteLine(gesturesMessage);
       
   217                     
       
   218                     foreach (var socket in allSockets.ToList())
       
   219                     {
       
   220                         socket.Send(gesturesMessage);
       
   221                     }
       
   222 
       
   223                     //On démarre le timer.
       
   224                     _gesturesTimer.Start();
       
   225 
       
   226                     //Console.WriteLine(gestureMessage);
       
   227                 //}
       
   228             }
       
   229         }
       
   230 
       
   231         /*
       
   232         * Méthode appelée lorsqu'on doit entrer dans un autre mode.
       
   233         */
       
   234         public void ModeNotification(String code)
       
   235         {
       
   236             //Si le code vient d'être envoyé, on passe.
       
   237             /*if (lastCode.Equals(code))
       
   238                 return;
       
   239             lastCode = code;*/
       
   240             //Si on a été notifié.
       
   241             if (!modLocked)
       
   242             {
       
   243                 modLocked = true;
       
   244 
       
   245                 //On crée un message contenant le code à envoyer.
       
   246                 //if (!modeMessageCreated)
       
   247                 //{
       
   248                     modeMessageCreated = true;
       
   249                     modeMessage = "2-" + code;
       
   250                     //On démarre le timer.
       
   251 
       
   252                     foreach (var socket in allSockets.ToList())
       
   253                     {
       
   254                         socket.Send(modeMessage);
       
   255                     }
       
   256                     _userPositionTimer.Start();
       
   257 
       
   258                     //Console.WriteLine(modeMessage);
       
   259                 //}
       
   260             }
       
   261         }
       
   262 
       
   263         /*
       
   264         * Méthode de callback vérifiant toutes les 25 ms les nouvelles notifications.
       
   265         * Il est à noter que si le temps de rafraîchissement des trop rapide, les messages n'ont pas
       
   266         * le temps d'être envoyés.
       
   267         */
       
   268         private void ThreadPoolCallback(Object threadContext)
       
   269         {
       
   270             while (true)
       
   271             {
       
   272                 /*//S'il existe un message de gesture.
       
   273                 if (gesturesMessage != null && !gesturesMessage.Equals(""))// && !gesturesMessage.Equals(prevGestureMessage))
       
   274                 {
       
   275                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   276                     foreach (var socket in allSockets.ToList())
       
   277                     {
       
   278                         socket.Send(gesturesMessage);
       
   279                         //prevGestureMessage = gesturesMessage;
       
   280                     }
       
   281                 }
       
   282 
       
   283                 //S'il existe un message de mode.
       
   284                 if (modeMessage != null && !modeMessage.Equals(""))// && !modeMessage.Equals(prevModeMessage))
       
   285                 {
       
   286                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   287                     foreach (var socket in allSockets.ToList())
       
   288                     {
       
   289                         socket.Send(modeMessage);
       
   290                         //prevModeMessage = modeMessage;
       
   291                     }
       
   292                 }*/
       
   293 
       
   294                 //Si la main gauche est détectée.
       
   295                 if (leftHandMessage != null && !leftHandMessage.Equals("") && !leftHandMessage.Equals(prevLeftHandMessage))
       
   296                 {
       
   297                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   298                     foreach (var socket in allSockets.ToList())
       
   299                     {
       
   300                         socket.Send(leftHandMessage);
       
   301                         prevLeftHandMessage = leftHandMessage;
       
   302                     }
       
   303                 }
       
   304                 //Si la main droite est détectée.
       
   305                 if (rightHandMessage != null && !rightHandMessage.Equals("") && !rightHandMessage.Equals(prevRightHandMessage))
       
   306                 {
       
   307                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   308                     foreach (var socket in allSockets.ToList())
       
   309                     {
       
   310                         socket.Send(rightHandMessage);
       
   311                         prevRightHandMessage = rightHandMessage;
       
   312                     }
       
   313                 }
       
   314                 
       
   315                 //On attend 25 ms.
       
   316                 Thread.Sleep(25);
       
   317 
       
   318                 //Si une gesture a été effectuée et que le délai d'attente est expiré.
       
   319                 if (gesturesMessageCreated && !gestureLocked)
       
   320                 {
       
   321                     //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture.
       
   322                     gesturesMessageCreated = false;
       
   323                     gesturesMessage = "";
       
   324                 }
       
   325 
       
   326                 //Si un mode a été effectuée et que le délai d'attente est expiré.
       
   327                 if (modeMessageCreated && !modLocked)
       
   328                 {
       
   329                     //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture.
       
   330                     modeMessageCreated = false;
       
   331                     modeMessage = "";
       
   332                 }
       
   333             }
       
   334         }
       
   335 
       
   336         /*
       
   337          * Getters et Setters
       
   338          */
       
   339         public void setTimerElapsing(int _timerElapsing)
       
   340         {
       
   341             timerElapsing = _timerElapsing;
       
   342         }
       
   343 
       
   344         public int getTimerElapsing()
       
   345         {
       
   346             return timerElapsing;
       
   347         }
       
   348     }
       
   349 }