Dreamine.Communication.RabbitMQ
1.0.1
Dreamine.Communication.RabbitMQ 통신 기능과 관련 API를 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
RabbitMqMessageBus.cs
이 파일의 문서화 페이지로 가기
1
using
System.Text.Json;
2
using
Dreamine.Communication.Abstractions.Enums;
3
using
Dreamine.Communication.Abstractions.Interfaces;
4
using
Dreamine.Communication.Abstractions.Models;
5
using
Dreamine.Communication.RabbitMQ.Infrastructure
;
6
using
Dreamine.Communication.RabbitMQ.Options
;
7
8
namespace
Dreamine.Communication.RabbitMQ.Buses
;
9
26
public
sealed
class
RabbitMqMessageBus
: IMessageBus
27
{
36
private
readonly
RabbitMqMessageBusOptions
_options
;
45
private
readonly
IRabbitMqConnectionFactory
_connectionFactory
;
54
private
readonly Dictionary<string, List<Func<MessageEnvelope, CancellationToken, Task>>>
_handlers
=
new
();
63
private
readonly
object
_syncRoot
=
new
();
64
73
private
IRabbitMqConnection
?
_connection
;
82
private
IRabbitMqChannel
?
_channel
;
91
private
string
?
_consumerTag
;
92
109
public
RabbitMqMessageBus
(
RabbitMqMessageBusOptions
options)
110
: this(options, new
RabbitMqClientConnectionFactory
())
111
{
112
}
113
146
public
RabbitMqMessageBus
(
147
RabbitMqMessageBusOptions
options,
148
IRabbitMqConnectionFactory
connectionFactory)
149
{
150
_options
= options ??
throw
new
ArgumentNullException(nameof(options));
151
_connectionFactory
= connectionFactory ??
throw
new
ArgumentNullException(nameof(connectionFactory));
152
ValidateOptions
(
_options
);
153
}
154
163
public
ConnectionState
State
{
get
;
private
set
; } = ConnectionState.Disconnected;
164
173
public
TransportKind
Kind
=> TransportKind.RabbitMq;
174
199
public
Task
ConnectAsync
(CancellationToken cancellationToken =
default
)
200
{
201
cancellationToken.ThrowIfCancellationRequested();
202
203
if
(
State
== ConnectionState.Connected)
204
{
205
return
Task.CompletedTask;
206
}
207
208
State
= ConnectionState.Connecting;
209
210
try
211
{
212
_connection
=
_connectionFactory
.CreateConnection(
_options
);
213
_channel
=
_connection
.CreateChannel();
214
215
DeclareTopology
(
_channel
);
216
217
State
= ConnectionState.Connected;
218
return
Task.CompletedTask;
219
}
220
catch
221
{
222
State
= ConnectionState.Faulted;
223
Cleanup
();
224
throw
;
225
}
226
}
227
268
public
Task
PublishAsync
(
269
MessageEnvelope message,
270
CancellationToken cancellationToken =
default
)
271
{
272
ArgumentNullException.ThrowIfNull(message);
273
cancellationToken.ThrowIfCancellationRequested();
274
275
if
(
_channel
is
null
||
State
!= ConnectionState.Connected)
276
{
277
throw
new
InvalidOperationException(
"RabbitMQ message bus is not connected."
);
278
}
279
280
var route =
string
.IsNullOrWhiteSpace(message.Route)
281
? _options.RoutingKey
282
: message.Route;
283
284
var body = JsonSerializer.SerializeToUtf8Bytes(message);
285
286
var properties =
_channel
.CreateBasicProperties();
287
properties.Persistent =
_options
.PersistentMessages;
288
properties.ContentType =
"application/json"
;
289
properties.Type = nameof(MessageEnvelope);
290
291
_channel
.BasicPublish(
292
exchange:
_options
.ExchangeName,
293
routingKey: route,
294
mandatory:
false
,
295
properties: properties,
296
body: body);
297
298
return
Task.CompletedTask;
299
}
300
349
public
Task
SubscribeAsync
(
350
string
route,
351
Func<MessageEnvelope, CancellationToken, Task> handler,
352
CancellationToken cancellationToken =
default
)
353
{
354
ArgumentException.ThrowIfNullOrWhiteSpace(route);
355
ArgumentNullException.ThrowIfNull(handler);
356
cancellationToken.ThrowIfCancellationRequested();
357
358
if
(
_channel
is
null
||
State
!= ConnectionState.Connected)
359
{
360
throw
new
InvalidOperationException(
"RabbitMQ message bus is not connected."
);
361
}
362
363
lock (
_syncRoot
)
364
{
365
if
(!
_handlers
.TryGetValue(route, out var handlers))
366
{
367
handlers = [];
368
_handlers
[route] = handlers;
369
}
370
371
handlers.Add(handler);
372
}
373
374
_channel
.QueueBind(
375
queue:
_options
.QueueName,
376
exchange:
_options
.ExchangeName,
377
routingKey: route);
378
379
if
(!
string
.IsNullOrWhiteSpace(
_consumerTag
))
380
{
381
return
Task.CompletedTask;
382
}
383
384
_consumerTag
=
_channel
.BasicConsume(
385
queue:
_options
.QueueName,
386
autoAck:
false
,
387
onReceived: (delivery, token) =>
HandleReceivedAsync
(
388
delivery,
389
token.CanBeCanceled ? token : cancellationToken));
390
391
return
Task.CompletedTask;
392
}
393
418
public
Task
DisconnectAsync
(CancellationToken cancellationToken =
default
)
419
{
420
cancellationToken.ThrowIfCancellationRequested();
421
422
State
= ConnectionState.Disconnecting;
423
424
try
425
{
426
Cleanup
();
427
State
= ConnectionState.Disconnected;
428
return
Task.CompletedTask;
429
}
430
catch
431
{
432
State
= ConnectionState.Faulted;
433
throw
;
434
}
435
}
436
453
public
async ValueTask
DisposeAsync
()
454
{
455
await
DisconnectAsync
().ConfigureAwait(
false
);
456
}
457
498
private
async Task
HandleReceivedAsync
(
499
RabbitMqDelivery
delivery,
500
CancellationToken cancellationToken)
501
{
502
if
(
_channel
is
null
)
503
{
504
return
;
505
}
506
507
try
508
{
509
var message = JsonSerializer.Deserialize<MessageEnvelope>(delivery.
Body
.Span);
510
511
if
(message is
null
)
512
{
513
_channel
.BasicReject(delivery.
DeliveryTag
, requeue:
false
);
514
return
;
515
}
516
517
var route =
string
.IsNullOrWhiteSpace(message.Route)
518
? delivery.RoutingKey
519
: message.Route;
520
521
List<Func<MessageEnvelope, CancellationToken, Task>> handlers;
522
523
lock (
_syncRoot
)
524
{
525
if
(!
_handlers
.TryGetValue(route, out var routeHandlers) &&
526
!
_handlers
.TryGetValue(delivery.
RoutingKey
, out routeHandlers))
527
{
528
handlers = [];
529
}
530
else
531
{
532
handlers =
new
List<Func<MessageEnvelope, CancellationToken, Task>>(routeHandlers);
533
}
534
}
535
536
if
(handlers.Count == 0)
537
{
538
_channel
.BasicAck(delivery.
DeliveryTag
, multiple:
false
);
539
return
;
540
}
541
542
foreach
(var handler
in
handlers)
543
{
544
await handler(message, cancellationToken).ConfigureAwait(
false
);
545
}
546
547
_channel
.BasicAck(delivery.
DeliveryTag
, multiple:
false
);
548
}
549
catch
550
{
551
try
552
{
553
_channel
.BasicNack(
554
delivery.
DeliveryTag
,
555
multiple:
false
,
556
requeue:
_options
.RequeueOnHandlerError);
557
}
558
catch
559
{
560
// Ignore acknowledgement failure during shutdown or channel fault.
561
}
562
563
throw
;
564
}
565
}
566
583
private
void
DeclareTopology
(
IRabbitMqChannel
channel)
584
{
585
channel.
ExchangeDeclare
(
586
exchange:
_options
.ExchangeName,
587
type:
_options
.ExchangeType,
588
durable:
_options
.Durable,
589
autoDelete:
_options
.AutoDelete);
590
591
channel.
QueueDeclare
(
592
queue:
_options
.QueueName,
593
durable:
_options
.Durable,
594
exclusive:
_options
.Exclusive,
595
autoDelete:
_options
.AutoDelete);
596
597
channel.
QueueBind
(
598
queue:
_options
.QueueName,
599
exchange:
_options
.ExchangeName,
600
routingKey:
_options
.RoutingKey);
601
}
602
611
private
void
Cleanup
()
612
{
613
lock (
_syncRoot
)
614
{
615
_handlers
.Clear();
616
}
617
618
if
(
_channel
is not
null
)
619
{
620
try
621
{
622
if
(!
string
.IsNullOrWhiteSpace(
_consumerTag
))
623
{
624
_channel
.BasicCancel(
_consumerTag
);
625
}
626
}
627
catch
628
{
629
// Ignore consumer cancel failure during cleanup.
630
}
631
632
try
633
{
634
if
(
_channel
.IsOpen)
635
{
636
_channel
.Close();
637
}
638
}
639
catch
640
{
641
// Ignore channel close failure during cleanup.
642
}
643
644
_channel
.Dispose();
645
_channel
=
null
;
646
}
647
648
if
(
_connection
is not
null
)
649
{
650
try
651
{
652
if
(
_connection
.IsOpen)
653
{
654
_connection
.Close();
655
}
656
}
657
catch
658
{
659
// Ignore connection close failure during cleanup.
660
}
661
662
_connection
.Dispose();
663
_connection
=
null
;
664
}
665
666
_consumerTag
=
null
;
667
}
668
701
private
static
void
ValidateOptions
(
RabbitMqMessageBusOptions
options)
702
{
703
ArgumentException.ThrowIfNullOrWhiteSpace(options.
HostName
);
704
ArgumentException.ThrowIfNullOrWhiteSpace(options.
VirtualHost
);
705
ArgumentException.ThrowIfNullOrWhiteSpace(options.
UserName
);
706
ArgumentException.ThrowIfNullOrWhiteSpace(options.
Password
);
707
ArgumentException.ThrowIfNullOrWhiteSpace(options.
ExchangeName
);
708
ArgumentException.ThrowIfNullOrWhiteSpace(options.
QueueName
);
709
ArgumentException.ThrowIfNullOrWhiteSpace(options.
RoutingKey
);
710
ArgumentException.ThrowIfNullOrWhiteSpace(options.
ExchangeType
);
711
712
if
(options.
Port
<= 0 || options.
Port
> 65535)
713
{
714
throw
new
ArgumentOutOfRangeException(nameof(options.
Port
));
715
}
716
}
717
}
Dreamine.Communication.RabbitMQ.Buses
Definition
RabbitMqMessageBus.cs:8
Dreamine.Communication.RabbitMQ.Infrastructure
Definition
IRabbitMqBasicProperties.cs:1
Dreamine.Communication.RabbitMQ.Options
Definition
RabbitMqMessageBusOptions.cs:1
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._consumerTag
string? _consumerTag
Definition
RabbitMqMessageBus.cs:91
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._syncRoot
readonly object _syncRoot
Definition
RabbitMqMessageBus.cs:63
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.ValidateOptions
static void ValidateOptions(RabbitMqMessageBusOptions options)
Definition
RabbitMqMessageBus.cs:701
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._options
readonly RabbitMqMessageBusOptions _options
Definition
RabbitMqMessageBus.cs:36
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._connection
IRabbitMqConnection? _connection
Definition
RabbitMqMessageBus.cs:73
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.HandleReceivedAsync
async Task HandleReceivedAsync(RabbitMqDelivery delivery, CancellationToken cancellationToken)
Definition
RabbitMqMessageBus.cs:498
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.PublishAsync
Task PublishAsync(MessageEnvelope message, CancellationToken cancellationToken=default)
Definition
RabbitMqMessageBus.cs:268
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.DisconnectAsync
Task DisconnectAsync(CancellationToken cancellationToken=default)
Definition
RabbitMqMessageBus.cs:418
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._connectionFactory
readonly IRabbitMqConnectionFactory _connectionFactory
Definition
RabbitMqMessageBus.cs:45
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._handlers
readonly Dictionary< string, List< Func< MessageEnvelope, CancellationToken, Task > > > _handlers
Definition
RabbitMqMessageBus.cs:54
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.Kind
TransportKind Kind
Definition
RabbitMqMessageBus.cs:173
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.RabbitMqMessageBus
RabbitMqMessageBus(RabbitMqMessageBusOptions options, IRabbitMqConnectionFactory connectionFactory)
Definition
RabbitMqMessageBus.cs:146
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.ConnectAsync
Task ConnectAsync(CancellationToken cancellationToken=default)
Definition
RabbitMqMessageBus.cs:199
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.SubscribeAsync
Task SubscribeAsync(string route, Func< MessageEnvelope, CancellationToken, Task > handler, CancellationToken cancellationToken=default)
Definition
RabbitMqMessageBus.cs:349
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.Cleanup
void Cleanup()
Definition
RabbitMqMessageBus.cs:611
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.DisposeAsync
async ValueTask DisposeAsync()
Definition
RabbitMqMessageBus.cs:453
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.State
ConnectionState State
Definition
RabbitMqMessageBus.cs:163
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.RabbitMqMessageBus
RabbitMqMessageBus(RabbitMqMessageBusOptions options)
Definition
RabbitMqMessageBus.cs:109
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus.DeclareTopology
void DeclareTopology(IRabbitMqChannel channel)
Definition
RabbitMqMessageBus.cs:583
Dreamine.Communication.RabbitMQ.Buses.RabbitMqMessageBus._channel
IRabbitMqChannel? _channel
Definition
RabbitMqMessageBus.cs:82
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqChannel
Definition
IRabbitMqChannel.cs:12
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqChannel.QueueBind
void QueueBind(string queue, string exchange, string routingKey)
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqChannel.QueueDeclare
void QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete)
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqChannel.ExchangeDeclare
void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete)
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqConnection
Definition
IRabbitMqConnection.cs:12
Dreamine.Communication.RabbitMQ.Infrastructure.IRabbitMqConnectionFactory
Definition
IRabbitMqConnectionFactory.cs:14
Dreamine.Communication.RabbitMQ.Infrastructure.RabbitMqClientConnectionFactory
Definition
RabbitMqClientConnectionFactory.cs:16
Dreamine.Communication.RabbitMQ.Infrastructure.RabbitMqDelivery
Definition
RabbitMqDelivery.cs:12
Dreamine.Communication.RabbitMQ.Infrastructure.RabbitMqDelivery.RoutingKey
string RoutingKey
Definition
RabbitMqDelivery.cs:73
Dreamine.Communication.RabbitMQ.Infrastructure.RabbitMqDelivery.DeliveryTag
ulong DeliveryTag
Definition
RabbitMqDelivery.cs:63
Dreamine.Communication.RabbitMQ.Infrastructure.RabbitMqDelivery.Body
ReadOnlyMemory< byte > Body
Definition
RabbitMqDelivery.cs:83
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions
Definition
RabbitMqMessageBusOptions.cs:12
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.HostName
string HostName
Definition
RabbitMqMessageBusOptions.cs:21
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.RoutingKey
string RoutingKey
Definition
RabbitMqMessageBusOptions.cs:91
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.QueueName
string QueueName
Definition
RabbitMqMessageBusOptions.cs:81
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.VirtualHost
string VirtualHost
Definition
RabbitMqMessageBusOptions.cs:41
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.UserName
string UserName
Definition
RabbitMqMessageBusOptions.cs:51
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.Password
string Password
Definition
RabbitMqMessageBusOptions.cs:61
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.ExchangeType
string ExchangeType
Definition
RabbitMqMessageBusOptions.cs:101
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.Port
int Port
Definition
RabbitMqMessageBusOptions.cs:31
Dreamine.Communication.RabbitMQ.Options.RabbitMqMessageBusOptions.ExchangeName
string ExchangeName
Definition
RabbitMqMessageBusOptions.cs:71
Buses
RabbitMqMessageBus.cs
다음에 의해 생성됨 :
1.17.0