Dreamine.Communication.Serial
1.0.2
Dreamine.Communication.Serial 통신 기능과 관련 API를 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
SerialPortTransport.cs
이 파일의 문서화 페이지로 가기
1
using
System.IO;
2
using
System.IO.Ports;
3
using
Dreamine.Communication.Abstractions.Enums;
4
using
Dreamine.Communication.Abstractions.Interfaces;
5
using
Dreamine.Communication.Abstractions.Models;
6
using
Dreamine.Communication.Core.Framing;
7
using
Dreamine.Communication.Core.Protocols;
8
using
Dreamine.Communication.Serial.Options
;
9
10
namespace
Dreamine.Communication.Serial.Ports
;
11
20
public
sealed
class
SerialPortTransport
: IMessageTransport
21
{
30
private
readonly
SerialPortTransportOptions
_options
;
39
private
readonly IMessageProtocolAdapter
_protocolAdapter
;
48
private
readonly IMessageFrameCodec
_frameCodec
;
49
58
private
SerialPort?
_serialPort
;
67
private
CancellationTokenSource?
_receiveLoopCts
;
76
private
Task?
_receiveLoopTask
;
85
private
int
_state
= (int)ConnectionState.Disconnected;
86
103
public
SerialPortTransport
(
SerialPortTransportOptions
options)
104
: this(
105
options,
106
new DreamineEnvelopeProtocolAdapter(),
107
new LengthPrefixedMessageFrameCodec())
108
{
109
}
110
151
public
SerialPortTransport
(
152
SerialPortTransportOptions
options,
153
IMessageProtocolAdapter protocolAdapter,
154
IMessageFrameCodec frameCodec)
155
{
156
_options
= options ??
throw
new
ArgumentNullException(nameof(options));
157
_protocolAdapter
= protocolAdapter ??
throw
new
ArgumentNullException(nameof(protocolAdapter));
158
_frameCodec
= frameCodec ??
throw
new
ArgumentNullException(nameof(frameCodec));
159
160
ValidateOptions
(
_options
);
161
}
162
171
public
ConnectionState
State
=> (ConnectionState)Volatile.Read(ref
_state
);
172
181
public
TransportKind
Kind
=> TransportKind.Serial;
182
191
public
event
EventHandler<MessageEnvelope>?
MessageReceived
;
192
217
public
Task
ConnectAsync
(CancellationToken cancellationToken =
default
)
218
{
219
if
(
State
is ConnectionState.Connected or ConnectionState.Connecting)
220
{
221
return
Task.CompletedTask;
222
}
223
224
cancellationToken.ThrowIfCancellationRequested();
225
226
SetState
(ConnectionState.Connecting);
227
228
try
229
{
230
_serialPort
=
new
SerialPort(
231
_options
.PortName,
232
_options
.BaudRate,
233
_options
.Parity,
234
_options
.DataBits,
235
_options
.StopBits)
236
{
237
Handshake =
_options
.Handshake,
238
ReadTimeout =
_options
.ReadTimeoutMs,
239
WriteTimeout =
_options
.WriteTimeoutMs,
240
ReadBufferSize =
_options
.ReadBufferSize,
241
WriteBufferSize = _options.WriteBufferSize
242
};
243
244
_serialPort
.Open();
245
246
SetState
(ConnectionState.Connected);
247
248
_receiveLoopCts
=
new
CancellationTokenSource();
249
_receiveLoopTask
= Task.Run(
250
() =>
ReceiveLoopAsync
(
_receiveLoopCts
.Token),
251
_receiveLoopCts
.Token);
252
253
return
Task.CompletedTask;
254
}
255
catch
256
{
257
SetState
(ConnectionState.Faulted);
258
259
_serialPort
?.Dispose();
260
_serialPort
=
null
;
261
262
throw
;
263
}
264
}
265
290
public
async Task
DisconnectAsync
(CancellationToken cancellationToken =
default
)
291
{
292
if
(
State
== ConnectionState.Disconnected)
293
{
294
return
;
295
}
296
297
SetState
(ConnectionState.Disconnecting);
298
299
_receiveLoopCts
?.Cancel();
300
301
if
(
_serialPort
is not
null
)
302
{
303
try
304
{
305
if
(
_serialPort
.IsOpen)
306
{
307
_serialPort
.Close();
308
}
309
}
310
finally
311
{
312
_serialPort
.Dispose();
313
}
314
}
315
316
if
(
_receiveLoopTask
is not
null
)
317
{
318
try
319
{
320
await
_receiveLoopTask
.ConfigureAwait(
false
);
321
}
322
catch
(OperationCanceledException)
323
{
324
}
325
catch
(ObjectDisposedException)
326
{
327
}
328
catch
(InvalidOperationException)
329
{
330
}
331
catch
(IOException)
332
{
333
}
334
}
335
336
_receiveLoopCts
?.Dispose();
337
_receiveLoopCts
=
null
;
338
_receiveLoopTask
=
null
;
339
_serialPort
=
null
;
340
341
cancellationToken.ThrowIfCancellationRequested();
342
343
SetState
(ConnectionState.Disconnected);
344
}
345
386
public
async Task
SendAsync
(
387
MessageEnvelope message,
388
CancellationToken cancellationToken =
default
)
389
{
390
ArgumentNullException.ThrowIfNull(message);
391
392
if
(
_serialPort
is
null
||
393
!
_serialPort
.IsOpen ||
394
State
!= ConnectionState.Connected)
395
{
396
throw
new
InvalidOperationException(
"Serial port is not connected."
);
397
}
398
399
try
400
{
401
var payload =
_protocolAdapter
.Encode(message);
402
403
await
_frameCodec
.WriteFrameAsync(
404
_serialPort
.BaseStream,
405
payload,
406
cancellationToken)
407
.ConfigureAwait(
false
);
408
}
409
catch
410
{
411
SetState
(ConnectionState.Faulted);
412
CleanupSerialPort
();
413
414
throw
;
415
}
416
}
417
434
public
async ValueTask
DisposeAsync
()
435
{
436
await
DisconnectAsync
().ConfigureAwait(
false
);
437
}
438
463
private
async Task
ReceiveLoopAsync
(CancellationToken cancellationToken)
464
{
465
if
(
_serialPort
is
null
)
466
{
467
return
;
468
}
469
470
try
471
{
472
while
(!cancellationToken.IsCancellationRequested &&
473
State
== ConnectionState.Connected)
474
{
475
var payload = await
_frameCodec
.ReadFrameAsync(
476
_serialPort
.BaseStream,
477
cancellationToken)
478
.ConfigureAwait(
false
);
479
480
if
(payload is
null
)
481
{
482
break
;
483
}
484
485
var message =
_protocolAdapter
.Decode(payload);
486
MessageReceived
?.Invoke(
this
, message);
487
}
488
489
if
(!cancellationToken.IsCancellationRequested &&
490
State
== ConnectionState.Connected)
491
{
492
SetState
(ConnectionState.Disconnected);
493
}
494
}
495
catch
(OperationCanceledException)
496
{
497
}
498
catch
(ObjectDisposedException)
499
{
500
}
501
catch
(InvalidOperationException)
502
{
503
if
(!cancellationToken.IsCancellationRequested)
504
{
505
SetState
(ConnectionState.Faulted);
506
}
507
}
508
catch
(IOException)
509
{
510
if
(!cancellationToken.IsCancellationRequested)
511
{
512
SetState
(ConnectionState.Faulted);
513
}
514
}
515
catch
516
{
517
if
(!cancellationToken.IsCancellationRequested)
518
{
519
SetState
(ConnectionState.Faulted);
520
CleanupSerialPort
();
521
}
522
}
523
}
524
533
private
void
CleanupSerialPort
()
534
{
535
try
536
{
537
if
(
_serialPort
is not
null
&&
_serialPort
.IsOpen)
538
{
539
_serialPort
.Close();
540
}
541
}
542
catch
543
{
544
}
545
546
try
547
{
548
_serialPort
?.Dispose();
549
}
550
catch
551
{
552
}
553
554
_serialPort
=
null
;
555
}
556
573
private
void
SetState
(ConnectionState state)
574
{
575
Interlocked.Exchange(ref
_state
, (
int
)state);
576
}
577
610
private
static
void
ValidateOptions
(
SerialPortTransportOptions
options)
611
{
612
ArgumentException.ThrowIfNullOrWhiteSpace(options.
PortName
);
613
614
if
(options.
BaudRate
<= 0)
615
{
616
throw
new
ArgumentOutOfRangeException(nameof(options.
BaudRate
));
617
}
618
619
if
(options.
DataBits
is < 5 or > 8)
620
{
621
throw
new
ArgumentOutOfRangeException(nameof(options.
DataBits
));
622
}
623
624
if
(options.
ReadTimeoutMs
< System.IO.Ports.SerialPort.InfiniteTimeout)
625
{
626
throw
new
ArgumentOutOfRangeException(nameof(options.
ReadTimeoutMs
));
627
}
628
629
if
(options.
WriteTimeoutMs
< System.IO.Ports.SerialPort.InfiniteTimeout)
630
{
631
throw
new
ArgumentOutOfRangeException(nameof(options.
WriteTimeoutMs
));
632
}
633
634
if
(options.
ReadBufferSize
<= 0)
635
{
636
throw
new
ArgumentOutOfRangeException(nameof(options.
ReadBufferSize
));
637
}
638
639
if
(options.
WriteBufferSize
<= 0)
640
{
641
throw
new
ArgumentOutOfRangeException(nameof(options.
WriteBufferSize
));
642
}
643
}
644
}
Dreamine.Communication.Serial.Options
Definition
SerialPortTransportOptions.cs:3
Dreamine.Communication.Serial.Ports
Definition
SerialPortTransport.cs:10
Dreamine.Communication.Serial.Options.SerialPortTransportOptions
Definition
SerialPortTransportOptions.cs:14
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.PortName
string PortName
Definition
SerialPortTransportOptions.cs:23
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.WriteTimeoutMs
int WriteTimeoutMs
Definition
SerialPortTransportOptions.cs:93
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.WriteBufferSize
int WriteBufferSize
Definition
SerialPortTransportOptions.cs:113
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.ReadTimeoutMs
int ReadTimeoutMs
Definition
SerialPortTransportOptions.cs:83
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.BaudRate
int BaudRate
Definition
SerialPortTransportOptions.cs:33
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.ReadBufferSize
int ReadBufferSize
Definition
SerialPortTransportOptions.cs:103
Dreamine.Communication.Serial.Options.SerialPortTransportOptions.DataBits
int DataBits
Definition
SerialPortTransportOptions.cs:43
Dreamine.Communication.Serial.Ports.SerialPortTransport.ReceiveLoopAsync
async Task ReceiveLoopAsync(CancellationToken cancellationToken)
Definition
SerialPortTransport.cs:463
Dreamine.Communication.Serial.Ports.SerialPortTransport._state
int _state
Definition
SerialPortTransport.cs:85
Dreamine.Communication.Serial.Ports.SerialPortTransport._receiveLoopTask
Task? _receiveLoopTask
Definition
SerialPortTransport.cs:76
Dreamine.Communication.Serial.Ports.SerialPortTransport._serialPort
SerialPort? _serialPort
Definition
SerialPortTransport.cs:58
Dreamine.Communication.Serial.Ports.SerialPortTransport.DisposeAsync
async ValueTask DisposeAsync()
Definition
SerialPortTransport.cs:434
Dreamine.Communication.Serial.Ports.SerialPortTransport.State
ConnectionState State
Definition
SerialPortTransport.cs:171
Dreamine.Communication.Serial.Ports.SerialPortTransport._options
readonly SerialPortTransportOptions _options
Definition
SerialPortTransport.cs:30
Dreamine.Communication.Serial.Ports.SerialPortTransport.ConnectAsync
Task ConnectAsync(CancellationToken cancellationToken=default)
Definition
SerialPortTransport.cs:217
Dreamine.Communication.Serial.Ports.SerialPortTransport.DisconnectAsync
async Task DisconnectAsync(CancellationToken cancellationToken=default)
Definition
SerialPortTransport.cs:290
Dreamine.Communication.Serial.Ports.SerialPortTransport._protocolAdapter
readonly IMessageProtocolAdapter _protocolAdapter
Definition
SerialPortTransport.cs:39
Dreamine.Communication.Serial.Ports.SerialPortTransport.SetState
void SetState(ConnectionState state)
Definition
SerialPortTransport.cs:573
Dreamine.Communication.Serial.Ports.SerialPortTransport._receiveLoopCts
CancellationTokenSource? _receiveLoopCts
Definition
SerialPortTransport.cs:67
Dreamine.Communication.Serial.Ports.SerialPortTransport.SerialPortTransport
SerialPortTransport(SerialPortTransportOptions options)
Definition
SerialPortTransport.cs:103
Dreamine.Communication.Serial.Ports.SerialPortTransport.SerialPortTransport
SerialPortTransport(SerialPortTransportOptions options, IMessageProtocolAdapter protocolAdapter, IMessageFrameCodec frameCodec)
Definition
SerialPortTransport.cs:151
Dreamine.Communication.Serial.Ports.SerialPortTransport.Kind
TransportKind Kind
Definition
SerialPortTransport.cs:181
Dreamine.Communication.Serial.Ports.SerialPortTransport.ValidateOptions
static void ValidateOptions(SerialPortTransportOptions options)
Definition
SerialPortTransport.cs:610
Dreamine.Communication.Serial.Ports.SerialPortTransport._frameCodec
readonly IMessageFrameCodec _frameCodec
Definition
SerialPortTransport.cs:48
Dreamine.Communication.Serial.Ports.SerialPortTransport.SendAsync
async Task SendAsync(MessageEnvelope message, CancellationToken cancellationToken=default)
Definition
SerialPortTransport.cs:386
Dreamine.Communication.Serial.Ports.SerialPortTransport.MessageReceived
EventHandler< MessageEnvelope >? MessageReceived
Definition
SerialPortTransport.cs:191
Dreamine.Communication.Serial.Ports.SerialPortTransport.CleanupSerialPort
void CleanupSerialPort()
Definition
SerialPortTransport.cs:533
Ports
SerialPortTransport.cs
다음에 의해 생성됨 :
1.17.0