blob: a3c6a8a78ce7106432ae301ce07e2d843aead7c7 (
plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
using System;
using System.Net;
using System.Net.Sockets;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MediaBrowser.Common.Net
{
/// <summary>
/// Provides a Udp Server
/// </summary>
public class UdpServer : IObservable<UdpReceiveResult>, IDisposable
{
/// <summary>
/// The _udp client
/// </summary>
private readonly UdpClient _udpClient;
/// <summary>
/// The _stream
/// </summary>
private readonly IObservable<UdpReceiveResult> _stream;
/// <summary>
/// Initializes a new instance of the <see cref="UdpServer" /> class.
/// </summary>
/// <param name="endPoint">The end point.</param>
/// <exception cref="System.ArgumentNullException">endPoint</exception>
public UdpServer(IPEndPoint endPoint)
{
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
_udpClient = new UdpClient(endPoint);
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//_udpClient.ExclusiveAddressUse = false;
_stream = CreateObservable();
}
/// <summary>
/// Creates the observable.
/// </summary>
/// <returns>IObservable{UdpReceiveResult}.</returns>
private IObservable<UdpReceiveResult> CreateObservable()
{
return Observable.Create<UdpReceiveResult>(obs =>
Observable.FromAsync(() => _udpClient.ReceiveAsync())
.Subscribe(obs))
.Repeat()
.Retry()
.Publish()
.RefCount();
}
/// <summary>
/// Subscribes the specified observer.
/// </summary>
/// <param name="observer">The observer.</param>
/// <returns>IDisposable.</returns>
/// <exception cref="System.ArgumentNullException">observer</exception>
public IDisposable Subscribe(IObserver<UdpReceiveResult> observer)
{
if (observer == null)
{
throw new ArgumentNullException("observer");
}
return _stream.Subscribe(observer);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
if (dispose)
{
_udpClient.Close();
}
}
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="endPoint">The end point.</param>
/// <returns>Task{System.Int32}.</returns>
/// <exception cref="System.ArgumentNullException">data</exception>
public async Task<int> SendAsync(string data, IPEndPoint endPoint)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
var bytes = Encoding.UTF8.GetBytes(data);
return await _udpClient.SendAsync(bytes, bytes.Length, endPoint).ConfigureAwait(false);
}
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="endPoint">The end point.</param>
/// <returns>Task{System.Int32}.</returns>
/// <exception cref="System.ArgumentNullException">bytes</exception>
public async Task<int> SendAsync(byte[] bytes, IPEndPoint endPoint)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
return await _udpClient.SendAsync(bytes, bytes.Length, endPoint).ConfigureAwait(false);
}
}
}
|