middleware/Communication/WSServer.cs
changeset 29 fcf435874395
child 37 37ebedd84755
equal deleted inserted replaced
28:9ccef81f02ab 29:fcf435874395
       
     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 : WSServer
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Reçoit des notifications du module sous-module Tracking.
       
    19  * Traduit les notifications sous forme de strings et les envoie au Front IDILL via WebSocket.
       
    20  * Forme des messages :
       
    21  * - Notification de main dans le champ de recherche : Point3D converti en String indiquant la position de la main dans l'espace.
       
    22  * - Notification de gesture/mode : String.
       
    23  * - Paramètres de config : String.
       
    24  */
       
    25 
       
    26 using System;
       
    27 using System.Collections.Generic;
       
    28 using System.Linq;
       
    29 using System.Text;
       
    30 using System.Threading;
       
    31 using Fleck;
       
    32 using System.Timers;
       
    33 using System.Windows.Media.Media3D;
       
    34 
       
    35 namespace Trakers.Communication
       
    36 {
       
    37     public class WSServer
       
    38     {
       
    39         //Server WebSocket.
       
    40         WebSocketServer server;
       
    41         List<IWebSocketConnection> allSockets;
       
    42 
       
    43         //Permet de savoir si un curseur pour la main gauche/droite a été créé.
       
    44         private bool leftHandCursorCreated;
       
    45         private bool rightHandCursorCreated;
       
    46         private bool messageCreated;
       
    47         private bool gestureLocked, modLocked;
       
    48         //Intervalle minimum entre les gestures.
       
    49         private int timerElapsing;
       
    50         //Timer.
       
    51         private System.Timers.Timer _timer;
       
    52         //Dernier code envoyé.
       
    53         private String lastCode;
       
    54         //Messages envoyés en WS.
       
    55         private String rightHandMessage, leftHandMessage, gestureMessage;
       
    56         //Messages précédents
       
    57         private String prevRightHandMessage, prevLeftHandMessage, prevGestureMessage;
       
    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 WSServer(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             messageCreated = false;
       
    74             gestureLocked = false;
       
    75             modLocked = false;
       
    76             lastCode = "";
       
    77 
       
    78             timerElapsing = _timerElapsing;
       
    79 
       
    80             rightHandMessage = leftHandMessage = gestureMessage = "";
       
    81 
       
    82             //On démarre le serveur WebSocket.
       
    83             server.Start(socket =>
       
    84             {
       
    85                 socket.OnOpen = () =>
       
    86                 {
       
    87                     Console.WriteLine("Open!");
       
    88                     allSockets.Add(socket);
       
    89                 };
       
    90                 socket.OnClose = () =>
       
    91                 {
       
    92                     Console.WriteLine("Close!");
       
    93                     allSockets.Remove(socket);
       
    94                 };
       
    95                 /*socket.OnMessage = message =>
       
    96                 {
       
    97                     Console.WriteLine(message);
       
    98                     allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
       
    99                 };*/
       
   100             });
       
   101 
       
   102             //On initialise le threadPool (appelé toutes les N ms).
       
   103             ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
       
   104 
       
   105             //On instancie le timer à N ms.
       
   106             _timer = new System.Timers.Timer(timerElapsing);
       
   107             //Dès que le timer est expiré, on appelle _timer_Elapsed.
       
   108             _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
       
   109 
       
   110             /*var input = Console.ReadLine();
       
   111             while (input != "exit")
       
   112             {
       
   113                 foreach (var socket in allSockets.ToList())
       
   114                 {
       
   115                     socket.Send(input);
       
   116                 }
       
   117                 input = Console.ReadLine();
       
   118             }*/
       
   119         }
       
   120 
       
   121         /*
       
   122          * Méthode appelée à l'expiration du timer pour les gestures et modes.
       
   123          */
       
   124         public void _timer_Elapsed(object sender, ElapsedEventArgs e)
       
   125         {
       
   126             //On débloque la détection de gesture.
       
   127             gestureLocked = false;
       
   128             //On débloque la notification de nouveau mode.
       
   129             modLocked = false;
       
   130             //On arrête le timer.
       
   131             _timer.Stop();
       
   132         }
       
   133 
       
   134         /*
       
   135         * Méthode appelée lors d'une notification de type : main gauche entrée dans le champ.
       
   136         */
       
   137         public void LeftHandTracked(Point3D pt)
       
   138         {
       
   139             leftHandMessage = "0-" + pt.X + ";" + pt.Y + ";" + pt.Z;
       
   140             //Si le curseur de la main gauche n'est pas créé, alors on le crée.
       
   141             if (!leftHandCursorCreated)
       
   142                 leftHandCursorCreated = true;
       
   143         }
       
   144 
       
   145         /*
       
   146         * Méthode appelée lors d'une notification de type : main droite entrée dans le champ.
       
   147         */
       
   148         public void RightHandTracked(Point3D pt)
       
   149         {
       
   150             rightHandMessage = "1-" + pt.X + ";" + pt.Y + ";" + pt.Z;
       
   151             //Si le curseur de la main droite n'est pas créé, alors on le crée.
       
   152             if (!rightHandCursorCreated)
       
   153                 rightHandCursorCreated = true;
       
   154         }
       
   155 
       
   156         /*
       
   157         * Méthode appelée lors d'une notification de type : main gauche sortie du champ.
       
   158         */
       
   159         public void LeftHandQuit()
       
   160         {
       
   161             leftHandMessage = "";
       
   162             //Si le curseur de la main gauche existe, alors on le supprime.
       
   163             if (leftHandCursorCreated)
       
   164                 leftHandCursorCreated = false;
       
   165         }
       
   166 
       
   167         /*
       
   168         * Méthode appelée lors d'une notification de type : main droite sortie du champ.
       
   169         */
       
   170         public void RightHandQuit()
       
   171         {
       
   172             rightHandMessage = "";
       
   173             //Si le curseur de la main droite existe, alors on le supprime.
       
   174             if (rightHandCursorCreated)
       
   175                 rightHandCursorCreated = false;
       
   176         }
       
   177 
       
   178         /*
       
   179         * Méthode appelée lorsqu'une gesture a été détectée et que l'événement approprié a été lancé.
       
   180         */
       
   181         public void GesturePerformed(String code)
       
   182         {
       
   183             //Si le code vient d'être envoyé, on passe.
       
   184             if (lastCode.Equals(code))
       
   185                 return;
       
   186             lastCode = code;
       
   187             //Si une gesture a été effectuée, on bloque un certain temps.
       
   188             if (!gestureLocked)
       
   189             {
       
   190                 gestureLocked = true;
       
   191 
       
   192                 //On crée un message contenant le code à envoyer.
       
   193                 if (!messageCreated)
       
   194                 {
       
   195                     messageCreated = true;
       
   196                     gestureMessage = "2-" + code;
       
   197                     //On démarre le timer.
       
   198                     _timer.Start();
       
   199                 }
       
   200             }
       
   201         }
       
   202 
       
   203         /*
       
   204         * Méthode appelée lorsqu'on doit entrer dans un autre mode.
       
   205         */
       
   206         public void ModeNotification(String code)
       
   207         {
       
   208             //Si le code vient d'être envoyé, on passe.
       
   209             if (lastCode.Equals(code))
       
   210                 return;
       
   211             lastCode = code;
       
   212             //Si on a été notifié.
       
   213             if (!modLocked)
       
   214             {
       
   215                 modLocked = true;
       
   216 
       
   217                 //On crée un message contenant le code à envoyer.
       
   218                 if (!messageCreated)
       
   219                 {
       
   220                     messageCreated = true;
       
   221                     gestureMessage = "2-" + code;
       
   222                     //On démarre le timer.
       
   223                     _timer.Start();
       
   224                 }
       
   225             }
       
   226         }
       
   227 
       
   228         /*
       
   229         * Méthode de callback vérifiant toutes les 25 ms les nouvelles notifications.
       
   230         * Il est à noter que si le temps de rafraîchissement des trop rapide, les messages n'ont pas
       
   231         * le temps d'être envoyés.
       
   232         */
       
   233         private void ThreadPoolCallback(Object threadContext)
       
   234         {
       
   235             while (true)
       
   236             {
       
   237                 //S'il existe un message.
       
   238                 if (gestureMessage != null && !gestureMessage.Equals("") && !gestureMessage.Equals(prevGestureMessage))
       
   239                 {
       
   240                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   241                     foreach (var socket in allSockets.ToList())
       
   242                     {
       
   243                         socket.Send(gestureMessage);
       
   244                         prevGestureMessage = gestureMessage;
       
   245                     }
       
   246                 }
       
   247                 //Si la main gauche est détectée.
       
   248                 if (leftHandMessage != null && !leftHandMessage.Equals("") && !leftHandMessage.Equals(prevLeftHandMessage))
       
   249                 {
       
   250                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   251                     foreach (var socket in allSockets.ToList())
       
   252                     {
       
   253                         socket.Send(leftHandMessage);
       
   254                         prevLeftHandMessage = leftHandMessage;
       
   255                     }
       
   256                 }
       
   257                 //Si la main droite est détectée.
       
   258                 if (rightHandMessage != null && !rightHandMessage.Equals("") && !rightHandMessage.Equals(prevRightHandMessage))
       
   259                 {
       
   260                     //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   261                     foreach (var socket in allSockets.ToList())
       
   262                     {
       
   263                         socket.Send(rightHandMessage);
       
   264                         prevRightHandMessage = rightHandMessage;
       
   265                     }
       
   266                 }
       
   267                 
       
   268                 //On attend 25 ms.
       
   269                 Thread.Sleep(25);
       
   270 
       
   271                 //Si une gesture a été effectuée et que le délai d'attente est expiré.
       
   272                 if (messageCreated && !gestureLocked && !modLocked)
       
   273                 {
       
   274                     //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture.
       
   275                     messageCreated = false;
       
   276                     gestureMessage = "";
       
   277                 }
       
   278             }
       
   279         }
       
   280 
       
   281         /*
       
   282          * Getters et Setters
       
   283          */
       
   284         public void setTimerElapsing(int _timerElapsing)
       
   285         {
       
   286             timerElapsing = _timerElapsing;
       
   287         }
       
   288 
       
   289         public int getTimerElapsing()
       
   290         {
       
   291             return timerElapsing;
       
   292         }
       
   293     }
       
   294 }