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 } |
|