1+ import { Channel , Connection } from 'amqplib' ;
2+ import { CONNECT_EVENT , ERROR_EVENT , MESSAGE_EVENT , RQM_DEFAULT_URL , SUBSCRIBE , RQM_DEFAULT_QUEUE } from './../constants' ;
3+ import { Logger } from '@nestjs/common/services/logger.service' ;
4+ import { loadPackage } from '@nestjs/common/utils/load-package.util' ;
5+ import { ClientProxy } from './client-proxy' ;
6+ import { ClientOptions , RmqOptions } from '../interfaces' ;
7+
8+ let rqmPackage : any = { } ;
9+
10+ export class ClientRMQ extends ClientProxy {
11+ private readonly logger = new Logger ( ClientProxy . name ) ;
12+ private client : Connection = null ;
13+ private channel : Channel = null ;
14+ private url : string ;
15+ private queue : string ;
16+
17+ constructor (
18+ private readonly options : ClientOptions ) {
19+ super ( ) ;
20+ this . url =
21+ this . getOptionsProp < RmqOptions > ( this . options , 'url' ) || RQM_DEFAULT_URL ;
22+ this . queue =
23+ this . getOptionsProp < RmqOptions > ( this . options , 'queue' ) || RQM_DEFAULT_QUEUE ;
24+ rqmPackage = loadPackage ( 'amqplib' , ClientRMQ . name ) ;
25+ this . connect ( ) ;
26+ }
27+
28+ protected async publish ( messageObj , callback : ( err , result , disposed ?: boolean ) => void ) {
29+ try {
30+ if ( ! this . client ) {
31+ await this . connect ( ) ;
32+ }
33+ this . channel . assertQueue ( '' , { exclusive : true } ) . then ( responseQ => {
34+ messageObj . replyTo = responseQ . queue ;
35+ this . channel . consume ( responseQ . queue , ( message ) => {
36+ this . handleMessage ( message , this . client , callback )
37+ } , { noAck : true } ) ;
38+ this . channel . sendToQueue ( this . queue , Buffer . from ( JSON . stringify ( messageObj ) ) ) ;
39+ } ) ;
40+ } catch ( err ) {
41+ console . log ( err ) ;
42+ callback ( err , null ) ;
43+ }
44+ }
45+
46+ private async handleMessage ( message , server , callback ) : Promise < void > {
47+ if ( message ) {
48+ const { content, fields } = message ;
49+ const { err, response, isDisposed } = JSON . parse ( content . toString ( ) ) ;
50+ if ( isDisposed || err ) {
51+ callback ( {
52+ err,
53+ response : null ,
54+ isDisposed : true ,
55+ } ) ;
56+ this . channel . deleteQueue ( fields . routingKey ) ;
57+ }
58+ callback ( {
59+ err,
60+ response,
61+ } ) ;
62+ }
63+ }
64+
65+ public close ( ) : void {
66+ this . channel && this . channel . close ( ) ;
67+ this . client && this . client . close ( ) ;
68+ }
69+
70+ public handleError ( client : Connection ) : void {
71+ client . addListener ( ERROR_EVENT , err => this . logger . error ( err ) ) ;
72+ }
73+
74+ public async connect ( ) : Promise < any > {
75+ return new Promise ( async ( resolve , reject ) => {
76+ this . client = await rqmPackage . connect ( this . url ) ;
77+ this . channel = await this . client . createChannel ( ) ;
78+ this . channel . assertQueue ( this . queue , { durable : false } ) ;
79+ resolve ( ) ;
80+ } ) ;
81+ }
82+ }
0 commit comments