I'm using Redis on my Nestjs project. Therefor I'm making use of the package svtslv/nestjs-ioredis
I'm not very experienced yet in Nestjs (and Typescript). But I try to figure out how to get a second client connection (to the same database) because I want to work with a subscriber and publisher.
Something like next Node-implementation done in Nestjs when using this Nest-package:
const Redis = require("ioredis");
const redis = new Redis();
const pub = new Redis();
redis.subscribe("news", "music", (err, count) => {
// Now we are subscribed to both the 'news' and 'music' channels.
// `count` represents the number of channels we are currently subscribed to.
pub.publish("news", "Hello world!");
pub.publish("music", "Hello again!");
});
redis.on("message", (channel, message) => {
// Receive message Hello world! from channel news
// Receive message Hello again! from channel music
console.log("Receive message %s from channel %s", message, channel);
});
// There's also an event called 'messageBuffer', which is the same as 'message' except
// it returns buffers instead of strings.
redis.on("messageBuffer", (channel, message) => {
// Both `channel` and `message` are buffers.
});
RedisModule.forRoot({}, 'secondConnection')
#InjectRedis('secondConnection') private readonly redis: Redis
(Big thank you to the developer himself of this project)
Related
I'm trying to send a message using SignalR and it works if I send to everybody, but not to s specific user. I tried to use the ConnectionId that in theory should be unique, but every time I tried to use the same connectionId that I received by the client, it doesn't work.
The server-side:
public async Task SendMessage(string user, string message)
{
var a = Context.UserIdentifier;
await Clients.User(Context.ConnectionId).SendAsync("ReceiveMessage", user, message);
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Trying to pass the same ConnectionId in context doesn't send the message, only when I call Clients.All
The client is an android app and I'm not sure if I should register something on my client-side.
hubConnection = HubConnectionBuilder.create("http://192.168.1.5:3000/notification").build()
hubConnection.start()
hubConnection.on<String, String>(
"ReceiveMessage",
Action2 { user: String?, message: String? ->
requireActivity().runOnUiThread(java.lang.Runnable {
Toast.makeText(
context,
"I'm here.",
Toast.LENGTH_LONG
).show()
})
},
String::class.java,
String::class.java
)
You should use
await Clients.Client(Context.ConnectionId).SendAsync("ReceiveMessage", message);
It should works well.
SignalR allows messages to be sent to a particular client connection, all connections associated with a specific user, as well as to named groups of connections. => await Clients. User(userId).
if you want to send message to specific user in SignalR, easiest way is the use Form authentication. Also you can use your custom session with form authentication. Right after creation your session code put this code. FormsAuthentication.SetAuthCookie (username.Trim (), false); Then in signalR you can use this line for send message to this user:
I'm trying to implement scheduling mechanism by the masstransit/rabbitmq.
I've added the configuration as stated in the docs:
Uri schedulerEndpoint = new (Constants.MassTransit.SchedulerEndpoint);
services.AddMassTransit(mtConfiguration =>
{
mtConfiguration.AddMessageScheduler(schedulerEndpoint);
mtConfiguration.AddSagaStateMachine<ArcStateMachine, ArcProcess>(typeof(ArcSagaDefinition))
.Endpoint(e => e.Name = massTransitConfiguration.SagaQueueName)
.MongoDbRepository(mongoDbConfiguration.ConnectionString, r =>
{
r.DatabaseName = mongoDbConfiguration.DbName;
r.CollectionName = mongoDbConfiguration.CollectionName;
});
mtConfiguration.UsingRabbitMq((context, cfg) =>
{
cfg.UseMessageScheduler(schedulerEndpoint);
cfg.Host(new Uri(rabbitMqConfiguration.Host), hst =>
{
hst.Username(rabbitMqConfiguration.Username);
hst.Password(rabbitMqConfiguration.Password);
});
cfg.ConfigureEndpoints(context);
});
});
Then I'm sending a scheduled message using the Bus:
DateTime messageScheduleTime = DateTime.UtcNow + TimeSpan.FromMinutes(1);
await _MessageScheduler.SchedulePublish<ScheduledMessage>(messageScheduleTime, new
{
ActivationId = context.Data.ActivationId
});
_MessageCheduler is the IMessageScheduler instance.
I do see the Scheduler queue receive the scheduled message and I see the correct scheduledTime property in it but the message does not reach the state machine whenever its schedule should fire. Seems like I'm missing something in the configuration or some MassTransit service that is not started.
Please, assist.
If you actually read the documentation you would see that UseDelayedMessageScheduler is the proper configuration to use RabbitMQ for scheduling. And AddDelayedMessageScheduler for the container-based IMessageScheduler registration.
I create a consumer base to retrieve each message from RabbitMq. I'm using easynetq to consume the messages in which the consumer is configured by advanced mode because the queue has some different configurations. Once recevied a message a call async method to process each message. However, the consume method in the advanced doesn't have a async consume method. Do I have to call async method using Task.Run or Task.Factory.StartNew methods?
Some process may last long time and erros may occurs during the process. In the error cases, I need to reject the message and let the message into the queue again. When the process is finally complete successfully, the message can accept and remove it from the queue.
That's an example of my code:
var queue = _bus.Advanced.QueueDeclare(_queueName, durable: true);
_consumerResult = _bus.Advanced.Consume(queue, (body, properties, info) =>
{
var message = Encoding.UTF8.GetString(body);
if (string.IsNullOrWhiteSpace(message))
return;
var deserializeObject = JsonConvert.DeserializeObject<IntegrationEvent<T>>(message, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
TypeNameHandling = TypeNameHandling.Auto,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
});
deserializeObject.DeliveryTag = info.DeliverTag;
// I need to call a async method
ConsumeAsync(deserializeObject));
});
How I can accept and reject the message manually?
So its happened for the second time now. I believe what triggered the error was when I tried to do an update to my MongoDb server but I still don't know why this happens and I'd like to find out.
Basically I am sending json string data from a C# script to my front end with Signalr using this command:
_hubContext.Clients.All.SendAsync("ReceiveMail", json);
The issue is that my script keeps broadcasting this message (without any errors or issues) but my client side doesnt receive it (even though this broadcast has worked for weeks....). When I change the name of the broadcast to something different the data then makes its way to the client side perfectly.
Example:
//This broadcast worked fine for weeks but suddenly stopped working (without error)
_hubContext.Clients.All.SendAsync("ReceiveMail", json);
//Changed above broadcast to this and broadcast works perfectly fine again
_hubContext.Clients.All.SendAsync("ListenForMail", json);
TS Code:
constructor() {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:57697/chat')
.build();
this.hubConnection
.start()
.then(() => this.table())
.catch(err => console.log('Error while establishing connection :('));
this.hubConnection.on('ReceiveMail', (mailJson: string) => {
this.loadEmail(mailJson);
});
this.hubConnection.on('ReceiveConnection', (msg: string) => {
console.log('Connection: ' + msg);
});
}
Anyone have any insight into this issue?
The method name the C# code is calling doesn't match the methods you are listening for in the TS code - but I'll assume that's a typo. If it's not, then you need to make sure the .on methods use the same method names as the C# code.
Another thing you do need to change is where you start the connection E.G.
constructor() {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:57697/chat')
.build();
this.hubConnection.on('RetrieveMail', (mailJson: string) => {
this.loadEmail(mailJson);
});
this.hubConnection.on('ReceiveConnection', (msg: string) => {
console.log('Connection: ' + msg);
});
this.hubConnection
.start()
.then(() => this.table())
.catch(err => console.log('Error while establishing connection :('));
}
In the code above I have moved the .start() call to AFTER registering the on methods. You should do it this way because the hubconnection can start listening messages before the handlers are registered causing a race condition. Any messages sent won't be received if the on handler hasn't finished registering.
I have followed the steps explained in https://www.npmjs.com/package/sails-rabbitmq. And When I persist the data in Message DataModel, it gets saved in MongoDB as well as in RabbitMQ ( CloudAMQP.com ). But i am seeing this error message in the sails lift console.
sails-rabbitmq: waiting for orm hook to load before binding persistence handlers...
Any tips for avoiding this warning message?
As well my subscription program in api/services is not getting invoked.. For testing purpose, invoked this service from a sails controller, yet,
Message.getSubscribeSocket({ where: { stream: 'random' } })
.then(function (socket) {
socket.on('data', function (data) {
var message = JSON.parse(data);
// see, I told you it was "low-level"
// ...
});
});
Thanks in advance for your guidance