-
Notifications
You must be signed in to change notification settings - Fork 0
/
Networker.cs
121 lines (109 loc) · 4.05 KB
/
Networker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Makaretu.Dns;
namespace IPOCS
{
public class Networker
{
private TcpListener listener { get; set; }
private Thread listenerThread;
private bool _started { get; set; } = false;
private MulticastService mdns { get; set; }
private ServiceDiscovery mdnsServiceDiscovery { get; set; }
private static Networker instance;
public delegate void OnConnectDelegate(Client client);
public event OnConnectDelegate OnConnect;
public delegate bool? OnConnectionRequestDelegate(Client client, Protocol.Packets.ConnectionRequest request);
public event OnConnectionRequestDelegate OnConnectionRequest;
public event OnConnectDelegate OnDisconnect;
public delegate void OnListeningDelegate(bool isListening);
public event OnListeningDelegate OnListening;
public static Networker Instance
{
get
{
if (instance == null)
{
instance = new Networker();
}
return instance;
}
}
private Networker()
{
this.listenerThread = new Thread(new ThreadStart(this.listenerThreadStart));
this.listener = new TcpListener(IPAddress.Any, 10000);
}
~Networker()
{
if (_started)
{
this.isListening = false;
this.listenerThread.Join();
}
}
CancellationTokenSource stopToken;
public bool isListening
{
get
{
return _started;
}
set
{
if (value != _started)
{
if (value && !_started)
{
this.listenerThread = new Thread(new ThreadStart(this.listenerThreadStart));
this.listenerThread.Start();
this.stopToken = new CancellationTokenSource();
this.stopToken.Token.Register(() => listener.Stop());
mdns = new MulticastService((sourceInterfaces) => { return sourceInterfaces; });
mdnsServiceDiscovery = new ServiceDiscovery(mdns);
mdnsServiceDiscovery.Advertise(new ServiceProfile("ipocs", "_ipocs._tcp", 10000));
mdns.Start();
_started = value;
}
if (!value && _started)
{
Clients.ToList().ForEach((c) =>
{
c.Disconnect();
});
this.stopToken.Cancel();
this.listener.Stop();
mdns.Stop();
_started = value;
}
}
}
}
private async void listenerThreadStart()
{
this.OnListening?.Invoke(true);
this.listener.Start();
while (!this.stopToken.IsCancellationRequested)
{
try
{
var tcpClient = await Task.Run(() => listener.AcceptTcpClientAsync(), this.stopToken.Token);
var client = new Client(tcpClient);
client.OnConnectionRequest += (c, r) => { return OnConnectionRequest?.Invoke(c, r); };
client.OnDisconnect += (c) => { Clients.Remove(c); OnDisconnect?.Invoke(c); };
client.OnConnect += (c) => { Clients.Add(c); OnConnect?.Invoke(client); };
} catch (Exception) { }
}
this.OnListening?.Invoke(false);
}
private List<Client> Clients { get; } = new List<Client>();
}
}