I have two microservices with Nest.js both of them connected to RabbitMQ service (one is the publisher and one is the receiver)
From the publisher I am trying to send a message to the receiver and seems that its not doing anything at all
Publisher :
auth.module.ts :
imports:[ClientsModule.registerAsync([
{
name: 'RMQ_SERVICE',
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
transport: Transport.RMQ,
options: {
urls: [`amqp://${configService.get('RMQ_HOST')}:5672`],
queue: 'api-queue',
queueOptions: {
durable: false,
},
},
}),
inject: [ConfigService],
},
]),
]
auth.service.ts :
#Inject('RMQ_SERVICE') private readonly client: ClientProxy,
and using it like that :
this.client.send({ cmd: 'create-user-data' },{});
Receiver :
main.ts :
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.RMQ,
options: {
noAck: false,
urls: [`amqp://${process.env.RMQ_HOST}:5672`],
queue: 'api-queue',
queueOptions: {
durable: false,
},
},
});
await app.startAllMicroservices();
users-data.controler.ts :
#MessagePattern({ cmd: 'create-user-data'})
async createUserData() {
console.log('create-user-data');
}
cant see any errors also i have rabbitmq web monitor and cannot see there any messages
any idea what wrong ?
if ill use emit and EventPattern its working i dont understand why ?
ok so after long digging i just needed to do
const result = await this.client.send(
{ cmd: 'create-user-data' },
{
userId: user.id,
provider,
...socialUser,
},
);
await result.subscribe();
and i received the message on the receiver
Related
I had a working code before refactoring, but cannot seem to find the issue now. I am getting no errors, but my consumer is not receiving, neither does the rabbitmq management show a 2nd connection.
Module
#Module({
imports: [
TypeOrmModule.forFeature([User]),
forwardRef(() => ActionModule),
TypeFormModule,
ClientsModule.register([
{
name: 'MATCHING_SERVICE',
transport: Transport.RMQ,
options: {
urls: ['amqp://localhost:5672'],
queue: 'matching',
queueOptions: {
durable: true,
},
},
},
]),
],
providers: [UsersService],
exports: [UsersService],
controllers: [UsersController],
})
Service
constructor(
#Inject('MATCHING_SERVICE') private client: ClientProxy,
) {}
Function
async test() {
const message = await this.client.send({ cmd: 'greeting-async' }, 'Progressive Coder');
return message;
}
I stuck when connecting NestJS Bull to AWS Elasticache on deployment
On local I easily connect to Redis by
import { Module } from '#nestjs/common';
import { BullModule } from '#nestjs/bull';
#Module({
imports: [
BullModule.forRoot({
redis: {
host: 'localhost',
port: 6379,
password: 'secret',
},
}),
],
})
export class AppModule {}
I even try on https://app.redislabs.com/ a official Redis cloud. It still working.
But on deployment with Elasticache. There is no error on startup but the queue is not worked as expected
My code last year was worked, But now no response
import Redis from 'ioredis';
#Module({
imports: [
BullModule.forRoot({
createClient: () => {
return config.get('redis.cluster.host')
? new Redis.Cluster([
{
port: +config.get('redis.cluster.port'),
host: config.get('redis.cluster.host'),
},
])
: new Redis(+config.get('redis.standalone.port'), config.get('redis.standalone.host'));
},
}),
FeeQueue,
],
providers: [],
exports: [],
})
export class QueuesModule {}
Could you have time to help me. Thanks
I don't know if it'll be the same for you, but I just ran into a similar issue. The queue wasn't working, but no error logged. After a lot of testing, I finally got it to log an error saying that enableReadyCheck and maxRetriesPerRequest can't be used for bclients and subscibers. So I unset them:
BullModule.forRoot({
createClient: (type) => {
const opts =
type !== 'client'
? { enableReadyCheck: false, maxRetriesPerRequest: null }
: {}
return config.get('redis.cluster.host')
? new Redis.Cluster([{ host, port }], opts)
: new Redis({ host, port, ...opts});
},
})
When I installed the app for first time the push notification is not receiving, if I kill the app and open again the push notifications is working fine.
When I console the code and trigger the push notification manually through FCM , I found that the notification data is not receiving on the onMessage function and on getInitialNotification() the result shows as undefined.
Please check the below code for getting push notifications and also the packages and versions which I have used.
Packages :
"#react-native-firebase/messaging": "^7.5.0",
"#react-native-community/push-notification-ios": "^1.10.1",
"react-native-push-notification": "^8.1.1",
Code :
componentWillUnmount() {
if (Platform.OS === "ios" && this.messageListener1 && this.messageListener2) {
this.messageListener1();
this.messageListener2();
}
}
async requestUserPermission() {
const { navigate } = { ...this.props }
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
this.messageListener1 = messaging().onMessage(async remoteMessage => {
PushNotification.localNotification({
/* Android Only Properties */
id: remoteMessage.data.id, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
autoCancel: true, // (optional) default: true
vibrate: true, // (optional) default: true
vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
group: remoteMessage.data,
userInfo: {
data: remoteMessage.data,
},
title: remoteMessage.notification.title,
message: remoteMessage.notification.body,
});
});
messaging()
.getInitialNotification()
.then(async remoteMessage => {
if (remoteMessage) {
if (await GlobalStorage.handleInitialNotification(remoteMessage)) {
navigate(remoteMessage);
PushNotification.cancelLocalNotifications({ id: remoteMessage.data.id });
}
}
});
this.messageListener2 = messaging().onNotificationOpenedApp(remoteMessage => {
GlobalStorage.handleInitialNotification(remoteMessage)
navigate(remoteMessage);
PushNotification.cancelLocalNotifications({ id: remoteMessage.data.id });
});
Note : There is no issues in getting the FCM token.
I faced the same problem.
I tried all the packages and the result is the same in all of them.
Here's the situation:
*Everything is fine with the Notification integration.
*When you install the application for the first time, there is no notification.
*When you open the application for the first time and kill it in the background and open it again and throw it into the background, everything works fine. You start receiving notifications.
It's really interesting. Has anyone experienced this and know what exactly is causing the issue?
The issue is only facing mainly on android device and here is solution I used to solve the issue
const { navigate,
} = { ...this.props }
PushNotification.configure({
onRegister: function (token) {
},
onNotification: function (notification) {
const clicked = notification.userInteraction ? notification.userInteraction : "";
notification.finish(PushNotificationIOS.FetchResult.NoData);
if (clicked) {
navigate(notification);s
PushNotification.cancelLocalNotifications({ id: notification.id });
} else if (!notification.foreground) {
navigate(notification);
PushNotification.cancelLocalNotifications({ id: notification.id });
}
else {
PushNotification.localNotification({
/* Android Only Properties */
channelId: "app_name", // (required)
channelName: "app_name", // (required)
id: notification.id, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
// autoCancel: true, // (optional) default: true
vibrate: true, // (optional) default: true
vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
group: notification.data, // (optional) add group to message
priority: "high", // (optional) set notification priority, default: high
visibility: "private", // (optional) set notification visibility, default: private
importance: "high",
userInfo: {
id: notification.id,
name: "name",
title: notification.title,
message: notification.message,
data: notification.data
},
title: notification.title,
message: notification.message,
});
}
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
senderID: "",
permissions: {
alert: true,
badge: true,
sound: true
},
popInitialNotification: true,
requestPermissions: true
});
Not getting ready event to be triggered. The connected event is triggered multiple times but ready is not. What am I doing wrong? Also connected event should also be triggered only once.
Implementation:
const client = new Cluster(
[
{
host: '127.0.0.1',
port: 7000,
},
],
{
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
},
},
);
client.on('ready', () => {
log.info('Ready to use Redis');
});
client.on('connect', () => {
log.info('Connected to Redis');
});
client.on('error', (x) => {
log.error(`Disconnected from Redis`);
});
Dockerhub:
redis-cluster:
image: grokzen/redis-cluster
environment:
MASTERS: 1
SLAVES_PER_MASTER: 1
ports:
- "7000:7000"
ioredis version: 4.26.0
i want to seed data onConnect, but i have access denied, using this query :
{
keystone: keystone {
adminMeta {
lists {
key
description
label
singular
plural
path
fields {
path
}
}
}
}
i have this error even iam using sudo, context.sudo().graphql.raw :
[
Error: Access denied
at /Users/sidalitemkit/work/web/yet/wirxe/wirxe-app/node_modules/#keystone-next/admin-ui/system/dist/admin-ui.cjs.dev.js:552:19
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async Promise.all (index 0)
at async Promise.all (index 0) {
locations: [ [Object] ],
path: [ 'keystone', 'adminMeta' ]
}
]
here my config :
export default auth.withAuth(
config({
db: {
adapter: 'prisma_postgresql',
url:
'postgres://admin:aj093bf7l6jdx5hm#wirxe-app-database-do-user-9126376-0.b.db.ondigitalocean.com:25061/wirxepool?schema=public&pgbouncer=true&sslmode=require',
onConnect: initialiseData,
},
ui: {
isAccessAllowed: (context) => !!context.session?.data,
},
lists,
session: withItemData(
statelessSessions({
maxAge: sessionMaxAge,
secret: sessionSecret,
}),
{ User: 'email' },
),
}),
);
i figured out that when i do :
isAccessAllowed: (context) => true
it's working
any advice here
context.sudo() disabled access control. there could be some issue with your query. isAccessAllowed: (context) => true is related to admin-ui and not to the backend implementation of graphql. This could be a bug please open a bug in the repo. They whould be able to fix it quickly.
I do not see sample initialiseData to try myself. Also the graphql is designed as such if you try to access some non existing item then it may give you access denied error even though there is not access control (all access set to true).
There is also another api which is easier in creating the initial items. You should use new list api, available as context.sudo().lists.<ListName>.createOne or createMany like this
const user = await context.sudo().lists.User.createOne({
data: {
name: 'Alice',
posts: { create: [{ title: 'My first post' }] },
},
query: 'id name posts { id title }',
});
or
const users = await context.lists.User.createOne({
data: [
{
data: {
name: 'Alice',
posts: [{ create: { title: 'Alices first post' } }],
},
},
{
data: {
name: 'Bob',
posts: [{ create: { title: 'Bobs first post' } }],
},
},
],
query: 'id name posts { id title }',
});
for more details see List Items API and Database Items API in their preview documentation.
You can find a working example in keystonejs repository (blog)
You have to await and pass context to the initialiseData() method. The onConnect hook already provides this context for you
also, you can look for an argument like '--seed-data' so it's only run once
and run the code as:
keystone --seed-data
export default auth.withAuth(
config({
db: {
adapter: 'prisma_postgresql',
url:
'postgres://admin:aj093bf7l6jdx5hm#wirxe-app-database-do-user-9126376-0.b.db.ondigitalocean.com:25061/wirxepool?schema=public&pgbouncer=true&sslmode=require',
async onConnect(context) {
if (process.argv.includes('--seed-data')) {
await initialiseData(context);
}
},
},
ui: {
isAccessAllowed: (context) => !!context.session?.data,
},
lists,
session: withItemData(
statelessSessions({
maxAge: sessionMaxAge,
secret: sessionSecret,
}),
{ User: 'email' },
),
}),
);