diff -r 0f31ebcc62b7 -r d2f735d7763f middleware/Communication/WSClient.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/middleware/Communication/WSClient.cs Fri Jun 29 15:37:26 2012 +0200 @@ -0,0 +1,349 @@ +/* +* This file is part of the TraKERS\Middleware package. +* +* (c) IRI +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +/* + * Projet : TraKERS + * Module : MIDDLEWARE + * Sous-Module : Communication + * Classe : WSClient + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Reçoit des notifications du Front IDILL. + * Interprète les positions des curseurs dans le temps à partir du top du front. + * + * STATUS : EN DEVELOPPEMENT. + * + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Fleck; +using System.Threading; +using System.Timers; +using System.Windows.Media.Media3D; + +namespace Communication +{ + public class WSClient + { + //Server WebSocket. + WebSocketServer server; + List allSockets; + + //Permet de savoir si un curseur pour la main gauche/droite a été créé. + private bool leftHandCursorCreated; + private bool rightHandCursorCreated; + private bool gesturesMessageCreated, modeMessageCreated; + private bool gestureLocked, modLocked; + //Intervalle minimum entre les gestures. + private int timerElapsing; + //Timers. + private System.Timers.Timer _gesturesTimer; + private System.Timers.Timer _userPositionTimer; + //Dernier code envoyé. + private String lastCode; + //Messages envoyés en WS. + private String rightHandMessage, leftHandMessage, gesturesMessage, modeMessage; + //Messages précédents + private String prevRightHandMessage, prevLeftHandMessage, prevGestureMessage, prevModeMessage; + + /* + * Constructeur : On initialise le serveur avec une adresse et un port, au début les curseurs + * ne sont pas créés et on indique au ThreadPool une fonction de callback de manière à vérifier + * s'il reçoit des notifications. + */ + public WSClient(String host, int port, int _timerElapsing) + { + FleckLog.Level = LogLevel.Debug; + allSockets = new List(); + server = new WebSocketServer(port, "ws://" + host + ":" + port); + + //Au départ, aucune main n'est dans le champ de recherche et aucune gesture n'est détectée. + leftHandCursorCreated = false; + rightHandCursorCreated = false; + gesturesMessageCreated = false; + modeMessageCreated = false; + gestureLocked = false; + modLocked = false; + lastCode = ""; + + timerElapsing = 500;// _timerElapsing; + + rightHandMessage = leftHandMessage = gesturesMessage = modeMessage = ""; + + //On démarre le serveur WebSocket. + server.Start(socket => + { + socket.OnOpen = () => + { + Console.WriteLine("Open!"); + allSockets.Add(socket); + }; + socket.OnClose = () => + { + Console.WriteLine("Close!"); + allSockets.Remove(socket); + }; + /*socket.OnMessage = message => + { + Console.WriteLine(message); + allSockets.ToList().ForEach(s => s.Send("Echo: " + message)); + };*/ + }); + + //On initialise le threadPool (appelé toutes les N ms). + ThreadPool.QueueUserWorkItem(ThreadPoolCallback); + + //On instancie le timer à N ms. + _gesturesTimer = new System.Timers.Timer(timerElapsing); + _userPositionTimer = new System.Timers.Timer(timerElapsing/5); + //Dès que le timer est expiré, on appelle _timer_Elapsed. + _gesturesTimer.Elapsed += new ElapsedEventHandler(_gesturesTimer_Elapsed); + _userPositionTimer.Elapsed += new ElapsedEventHandler(_userPositionTimer_Elapsed); + + /*var input = Console.ReadLine(); + while (input != "exit") + { + foreach (var socket in allSockets.ToList()) + { + socket.Send(input); + } + input = Console.ReadLine(); + }*/ + } + + /* + * Méthode appelée à l'expiration du timer pour les gestures et modes. + */ + public void _gesturesTimer_Elapsed(object sender, ElapsedEventArgs e) + { + //On débloque la détection de gesture. + gestureLocked = false; + //On débloque la notification de nouveau mode. + //modLocked = false; + lastCode = ""; + //On arrête le timer. + _gesturesTimer.Stop(); + } + + /* + * Méthode appelée à l'expiration du timer pour les positions d'utilisateur. + */ + public void _userPositionTimer_Elapsed(object sender, ElapsedEventArgs e) + { + //On débloque la détection de gesture. + //gestureLocked = false; + //On débloque la notification de nouveau mode. + modLocked = false; + lastCode = ""; + //On arrête le timer. + _userPositionTimer.Stop(); + } + + /* + * Méthode appelée lors d'une notification de type : main gauche entrée dans le champ. + */ + public void LeftHandTracked(Point3D pt) + { + leftHandMessage = "0-" + pt.X + ";" + pt.Y + ";" + pt.Z; + //Si le curseur de la main gauche n'est pas créé, alors on le crée. + if (!leftHandCursorCreated) + leftHandCursorCreated = true; + } + + /* + * Méthode appelée lors d'une notification de type : main droite entrée dans le champ. + */ + public void RightHandTracked(Point3D pt) + { + rightHandMessage = "1-" + pt.X + ";" + pt.Y + ";" + pt.Z; + //Si le curseur de la main droite n'est pas créé, alors on le crée. + if (!rightHandCursorCreated) + rightHandCursorCreated = true; + } + + /* + * Méthode appelée lors d'une notification de type : main gauche sortie du champ. + */ + public void LeftHandQuit() + { + leftHandMessage = ""; + //Si le curseur de la main gauche existe, alors on le supprime. + if (leftHandCursorCreated) + leftHandCursorCreated = false; + } + + /* + * Méthode appelée lors d'une notification de type : main droite sortie du champ. + */ + public void RightHandQuit() + { + rightHandMessage = ""; + //Si le curseur de la main droite existe, alors on le supprime. + if (rightHandCursorCreated) + rightHandCursorCreated = false; + } + + /* + * Méthode appelée lorsqu'une gesture a été détectée et que l'événement approprié a été lancé. + */ + public void GesturePerformed(String code) + { + //Si le code vient d'être envoyé, on passe. + /*if (lastCode.Equals(code)) + return; + lastCode = code;*/ + //Si une gesture a été effectuée, on bloque un certain temps. + if (!gestureLocked) + { + gestureLocked = true; + + //On crée un message contenant le code à envoyer. + //if (!gesturesMessageCreated) + //{ + gesturesMessageCreated = true; + gesturesMessage = "2-" + code; + + //Console.WriteLine(gesturesMessage); + + foreach (var socket in allSockets.ToList()) + { + socket.Send(gesturesMessage); + } + + //On démarre le timer. + _gesturesTimer.Start(); + + //Console.WriteLine(gestureMessage); + //} + } + } + + /* + * Méthode appelée lorsqu'on doit entrer dans un autre mode. + */ + public void ModeNotification(String code) + { + //Si le code vient d'être envoyé, on passe. + /*if (lastCode.Equals(code)) + return; + lastCode = code;*/ + //Si on a été notifié. + if (!modLocked) + { + modLocked = true; + + //On crée un message contenant le code à envoyer. + //if (!modeMessageCreated) + //{ + modeMessageCreated = true; + modeMessage = "2-" + code; + //On démarre le timer. + + foreach (var socket in allSockets.ToList()) + { + socket.Send(modeMessage); + } + _userPositionTimer.Start(); + + //Console.WriteLine(modeMessage); + //} + } + } + + /* + * Méthode de callback vérifiant toutes les 25 ms les nouvelles notifications. + * Il est à noter que si le temps de rafraîchissement des trop rapide, les messages n'ont pas + * le temps d'être envoyés. + */ + private void ThreadPoolCallback(Object threadContext) + { + while (true) + { + /*//S'il existe un message de gesture. + if (gesturesMessage != null && !gesturesMessage.Equals(""))// && !gesturesMessage.Equals(prevGestureMessage)) + { + //On l'envoie au client (au host et au port spécifiés dans le constructeur). + foreach (var socket in allSockets.ToList()) + { + socket.Send(gesturesMessage); + //prevGestureMessage = gesturesMessage; + } + } + + //S'il existe un message de mode. + if (modeMessage != null && !modeMessage.Equals(""))// && !modeMessage.Equals(prevModeMessage)) + { + //On l'envoie au client (au host et au port spécifiés dans le constructeur). + foreach (var socket in allSockets.ToList()) + { + socket.Send(modeMessage); + //prevModeMessage = modeMessage; + } + }*/ + + //Si la main gauche est détectée. + if (leftHandMessage != null && !leftHandMessage.Equals("") && !leftHandMessage.Equals(prevLeftHandMessage)) + { + //On l'envoie au client (au host et au port spécifiés dans le constructeur). + foreach (var socket in allSockets.ToList()) + { + socket.Send(leftHandMessage); + prevLeftHandMessage = leftHandMessage; + } + } + //Si la main droite est détectée. + if (rightHandMessage != null && !rightHandMessage.Equals("") && !rightHandMessage.Equals(prevRightHandMessage)) + { + //On l'envoie au client (au host et au port spécifiés dans le constructeur). + foreach (var socket in allSockets.ToList()) + { + socket.Send(rightHandMessage); + prevRightHandMessage = rightHandMessage; + } + } + + //On attend 25 ms. + Thread.Sleep(25); + + //Si une gesture a été effectuée et que le délai d'attente est expiré. + if (gesturesMessageCreated && !gestureLocked) + { + //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture. + gesturesMessageCreated = false; + gesturesMessage = ""; + } + + //Si un mode a été effectuée et que le délai d'attente est expiré. + if (modeMessageCreated && !modLocked) + { + //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture. + modeMessageCreated = false; + modeMessage = ""; + } + } + } + + /* + * Getters et Setters + */ + public void setTimerElapsing(int _timerElapsing) + { + timerElapsing = _timerElapsing; + } + + public int getTimerElapsing() + { + return timerElapsing; + } + } +}