Middleware:
config by config file
Front JS:
Examples created (pointers & gestures).
Installer that integers now Middleware + Front Processing + Front JS.
/*
* This file is part of the TraKERS\Middleware package.
*
* (c) IRI <http://www.iri.centrepompidou.fr/>
*
* 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 : WSServer
*
* Auteur : alexandre.bastien@iri.centrepompidou.fr
*
* Fonctionnalités : Reçoit des notifications du module sous-module Tracking.
* Traduit les notifications sous forme de strings et les envoie au Front IDILL via WebSocket.
* Forme des messages :
* - Notification de main dans le champ de recherche : Point3D converti en String indiquant la position de la main dans l'espace.
* - Notification de gesture/mode : String.
* - Paramètres de config : String.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Fleck;
using System.Timers;
using System.Windows.Media.Media3D;
namespace Trakers.Communication
{
public class WSServer
{
//Server WebSocket.
WebSocketServer server;
List<IWebSocketConnection> 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 WSServer(String host, int port, int _timerElapsing)
{
FleckLog.Level = LogLevel.Debug;
allSockets = new List<IWebSocketConnection>();
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);
};
});
//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);
}
/*
* 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 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 une gesture a été effectuée, on bloque un certain temps.
if (!gestureLocked)
{
gestureLocked = true;
//On crée un message contenant le code à envoyer.
gesturesMessageCreated = true;
gesturesMessage = "2-" + code;
//Console.WriteLine(gesturesMessage);
foreach (var socket in allSockets.ToList())
{
socket.Send(gesturesMessage);
}
//On démarre le timer.
_gesturesTimer.Start();
}
}
/*
* Méthode appelée lorsqu'on doit entrer dans un autre mode.
*/
public void ModeNotification(String code)
{
//Si on a été notifié.
if (!modLocked)
{
modLocked = true;
//On crée un message contenant le code à envoyer.
modeMessageCreated = true;
modeMessage = "2-" + code;
//On démarre le timer.
foreach (var socket in allSockets.ToList())
{
socket.Send(modeMessage);
}
_userPositionTimer.Start();
}
}
/*
* 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)
{
//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;
}
}
}