Dreamine.PLC.Omron.Fins 1.0.1
Dreamine.PLC.Omron.Fins 산업 자동화 및 I/O 기능을 제공합니다.
로딩중...
검색중...
일치하는것 없음
OmronFinsUdpSimulatorServer.cs
이 파일의 문서화 페이지로 가기
1using System.Net;
2using System.Net.Sockets;
3using Dreamine.PLC.Core.Memory;
4
6
15public sealed class OmronFinsUdpSimulatorServer : IAsyncDisposable
16{
34 private readonly InMemoryPlcMemory _memory;
52 private UdpClient? _udpClient;
61 private CancellationTokenSource? _cts;
70 private Task? _receiveTask;
71
97 : this(options, new InMemoryPlcMemory())
98 {
99 }
100
133 public OmronFinsUdpSimulatorServer(OmronFinsSimulatorServerOptions options, InMemoryPlcMemory memory)
134 {
135 _options = options ?? throw new ArgumentNullException(nameof(options));
136 _memory = memory ?? throw new ArgumentNullException(nameof(memory));
138 _protocol.StatusChanged += (_, message) => StatusChanged?.Invoke(this, message);
139 }
140
149 public event EventHandler<string>? StatusChanged;
150
159 public bool IsRunning => _udpClient is not null;
160
193 public Task StartAsync()
194 {
195 if (IsRunning)
196 {
197 return Task.CompletedTask;
198 }
199
200 var address = ParseAddress(_options.Host);
201
202 _cts = new CancellationTokenSource();
203 _udpClient = new UdpClient(new IPEndPoint(address, _options.Port));
205 StatusChanged?.Invoke(this, $"FINS UDP simulator listening on {_options.Host}:{_options.Port}.");
206 return Task.CompletedTask;
207 }
208
225 public async Task StopAsync()
226 {
227 if (!IsRunning)
228 {
229 return;
230 }
231
232 _cts?.Cancel();
233 _udpClient?.Dispose();
234 _udpClient = null;
235
236 if (_receiveTask is not null)
237 {
238 try
239 {
240 await _receiveTask.ConfigureAwait(false);
241 }
242 catch (OperationCanceledException)
243 {
244 }
245 catch (ObjectDisposedException)
246 {
247 }
248 catch (SocketException)
249 {
250 }
251 }
252
253 _cts?.Dispose();
254 _cts = null;
255 _receiveTask = null;
256 StatusChanged?.Invoke(this, "FINS UDP simulator stopped.");
257 }
258
275 public async ValueTask DisposeAsync()
276 {
277 await StopAsync().ConfigureAwait(false);
278 }
279
304 private static IPAddress ParseAddress(string host)
305 {
306 if (string.IsNullOrWhiteSpace(host) || host == "0.0.0.0" || host == "*" || host == "+")
307 {
308 return IPAddress.Any;
309 }
310
311 return IPAddress.TryParse(host, out var address) ? address : IPAddress.Any;
312 }
313
338 private async Task ReceiveLoopAsync(CancellationToken cancellationToken)
339 {
340 while (!cancellationToken.IsCancellationRequested && _udpClient is not null)
341 {
342 try
343 {
344 var request = await _udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
345 var response = _protocol.HandleRequest(request.Buffer);
346 await _udpClient.SendAsync(response, response.Length, request.RemoteEndPoint).ConfigureAwait(false);
347 }
348 catch (OperationCanceledException)
349 {
350 break;
351 }
352 catch (ObjectDisposedException)
353 {
354 break;
355 }
356 catch (SocketException ex)
357 {
358 StatusChanged?.Invoke(this, $"FINS UDP socket error: {ex.Message}");
359 }
360 catch (Exception ex)
361 {
362 StatusChanged?.Invoke(this, $"FINS UDP server error: {ex.Message}");
363 }
364 }
365 }
366}
OmronFinsUdpSimulatorServer(OmronFinsSimulatorServerOptions options, InMemoryPlcMemory memory)