Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 49e751db

Přidáno uživatelem Oto Šťáva před téměř 4 roky(ů)

Re #8900 - Implement client reconnection

Zobrazit rozdíly:

deltarobot-vr/Assets/DeltaRobotVr/Client.cs
4 4
using System.IO;
5 5
using System.Linq;
6 6
using System.Text;
7
using UnityEngine;
7 8

  
8 9
namespace DeltaRobotVr
9 10
{
......
55 56

  
56 57
        private const UInt32 PointLength = 12;
57 58

  
59
        private const int ReconnectPollMillis = 200;
60
        private const int ReconnectTimeMillis = 3000;
61

  
58 62
        
59 63
        private Thread _thread;
60 64
        
......
77 81
        private volatile bool _isConnected;
78 82
        private volatile string _eotMsg;
79 83

  
84
        private readonly object _reconnectTimeLock = new object();
85
        private DateTime _reconnectTime = DateTime.Now;
86

  
80 87
        static Client()
81 88
        {
82 89
        }
......
217 224
            }
218 225
        }
219 226

  
227
        public DateTime ReconnectTime
228
        {
229
            get
230
            {
231
                lock (_reconnectTimeLock)
232
                {
233
                    return _reconnectTime;
234
                }
235
            }
236
            private set
237
            {
238
                lock (_reconnectTimeLock)
239
                {
240
                    _reconnectTime = value;
241
                }
242
            }
243
        }
244

  
220 245
        private void ThreadProcedure()
221 246
        {
222
            try
247
            while (IsRunning)
223 248
            {
224
                var client = new TcpClient(DefaultServer, DefaultPort);
225
                var stream = client.GetStream();
226
                BinaryReader reader = new BinaryReader(stream);
227
                BinaryWriter writer = new BinaryWriter(stream);
228
                IsConnected = true;
229
                
230
                writer.Write(ProtocolMagicId);
231
                writer.Write(ProtocolMagicValue);
232
                writer.Write(ProtocolVersionId);
233
                writer.Write(ProtocolVersionValue);
234
                
235 249
                try
236 250
                {
251
                    using var client = new TcpClient(DefaultServer, DefaultPort);
252
                    using var stream = client.GetStream();
253
                    BinaryReader reader = new BinaryReader(stream);
254
                    BinaryWriter writer = new BinaryWriter(stream);
255
                    IsConnected = true;
256

  
257
                    SendProtocolPreamble(writer);
258

  
259
                    // main message reception loop
237 260
                    while (IsRunning && IsConnected)
238 261
                    {
239
                        var messageIdentifier = reader.ReadUInt16();
240
                        switch (messageIdentifier)
241
                        {
242
                            case ProtocolMagicId:
243
                                ProcessProtocolMagic(reader);
244
                                break;
245
                            case ProtocolVersionId:
246
                                ProcessProtocolVersion(reader);
247
                                break;
248
                            case PingId:
249
                                ProcessPing(reader, writer);
250
                                break;
251
                            case EotId:
252
                                ProcessEot(reader);
253
                                break;
254
                            case CurrentActuatorPositionId:
255
                                ProcessCurrentActuatorPosition(reader);
256
                                break;
257
                            case CurrentDirectionVectorId:
258
                                ProcessCurrentDirectionVector(reader);
259
                                break;
260
                            case DesiredDirectionVectorId:
261
                                ProcessDesiredDirectionVector(reader);
262
                                break;
263
                            case CurveId:
264
                                ProcessCurve(reader);
265
                                break;
266
                            default: //client tuto zpravu nezna
267
                                var sizeIdentifier = (UInt16) (messageIdentifier & 0xF000);
268
                                switch (sizeIdentifier)
269
                                {
270
                                    case Size8:
271
                                        Skip8(reader);
272
                                        break;
273
                                    case Size16:
274
                                        Skip16(reader);
275
                                        break;
276
                                    case Size32:
277
                                        Skip32(reader);
278
                                        break;
279
                                    case Size64:
280
                                        Skip64(reader);
281
                                        break;
282
                                    case Size128:
283
                                        Skip128(reader);
284
                                        break;
285
                                    case SizeVariable:
286
                                        SkipVariableLength(reader);
287
                                        break;
288
                                }
289

  
290
                                break;
291
                        }
262
                        ReadMessages(reader, writer);
292 263
                    }
293 264
                }
294
                finally
265
                catch (Exception e)
295 266
                {
296
                    stream.Close();
297
                    client.Close();
298
                    IsConnected = true;
267
                    if (e is SocketException || e is IOException)
268
                    {
269
                        Debug.LogWarning($"Connection error:\n{e}");
270
                    }
271
                    else
272
                    {
273
                        Debug.LogError($"Exception in communication thread:\n{e}");
274
                    }
275
                }
276
                
277
                // wait before reconnection - short polls to prevent blocking if application is closed
278
                ReconnectTime = DateTime.Now.AddMilliseconds(ReconnectTimeMillis);
279
                while (IsRunning && DateTime.Now < ReconnectTime)
280
                {
281
                    Thread.Sleep(ReconnectPollMillis);
299 282
                }
300 283
            }
301
            catch (Exception)
284
        }
285

  
286

  
287
        private void ReadMessages(BinaryReader reader, BinaryWriter writer)
288
        {
289
            var messageIdentifier = reader.ReadUInt16();
290
            switch (messageIdentifier)
302 291
            {
303
                Console.WriteLine("failed to connect");
292
                case ProtocolMagicId:
293
                    ProcessProtocolMagic(reader);
294
                    break;
295
                case ProtocolVersionId:
296
                    ProcessProtocolVersion(reader);
297
                    break;
298
                case PingId:
299
                    ProcessPing(reader, writer);
300
                    break;
301
                case EotId:
302
                    ProcessEot(reader);
303
                    break;
304
                case CurrentActuatorPositionId:
305
                    ProcessCurrentActuatorPosition(reader);
306
                    break;
307
                case CurrentDirectionVectorId:
308
                    ProcessCurrentDirectionVector(reader);
309
                    break;
310
                case DesiredDirectionVectorId:
311
                    ProcessDesiredDirectionVector(reader);
312
                    break;
313
                case CurveId:
314
                    ProcessCurve(reader);
315
                    break;
316
                default: // unknown message
317
                    var sizeIdentifier = (UInt16) (messageIdentifier & 0xF000);
318
                    switch (sizeIdentifier)
319
                    {
320
                        case Size8:
321
                            Skip8(reader);
322
                            break;
323
                        case Size16:
324
                            Skip16(reader);
325
                            break;
326
                        case Size32:
327
                            Skip32(reader);
328
                            break;
329
                        case Size64:
330
                            Skip64(reader);
331
                            break;
332
                        case Size128:
333
                            Skip128(reader);
334
                            break;
335
                        case SizeVariable:
336
                            SkipVariableLength(reader);
337
                            break;
338
                    }
339

  
340
                    break;
304 341
            }
305 342
        }
306 343

  
344
        private void SendProtocolPreamble(BinaryWriter writer)
345
        {
346
            writer.Write(ProtocolMagicId);
347
            writer.Write(ProtocolMagicValue);
348
            writer.Write(ProtocolVersionId);
349
            writer.Write(ProtocolVersionValue);
350
        }
307 351

  
308 352
        private void Skip8(BinaryReader reader)
309 353
        {

Také k dispozici: Unified diff