英文:
how to pass a message from go and consuming it from nestjs with rabbitmq?
问题
我有一个go
服务,它将消息发布到rabbitmq
,负责该部分的代码如下:
package main
import (
"log"
"github.com/streadway/amqp"
)
func main() {
conn, amqError := amqp.Dial("amqp://localhost:5672/")
if amqError != nil {
panic(amqError)
}
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
q, err := ch.QueueDeclare(
"default", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
body := `{ "body":"Hello...", "pattern":"test", "age":"20"}`
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
},
)
failOnError(err, "Failed to publish a message")
}
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
而消费消息的Nestjs
部分如下:
import { Controller } from '@nestjs/common';
import { Ctx, EventPattern, Payload, RmqContext } from '@nestjs/microservices';
@Controller()
export class AppController {
constructor() { }
@EventPattern("test")
getEventMessage(@Payload() data: any, @Ctx() context: RmqContext) {
console.log("data is -> ", data) // always undefined
console.log(
"content of message is -> ",
JSON.parse(
context.getMessage().content.toString() // from buffer to string
)
)
}
}
现在的问题是,我无法从data
中获取消息,而是需要从ctx
中解析它,另外,我需要以json
格式将消息发送到go中,而不跳过双引号,就像这样"\\""
。
英文:
I have a go
service that publishes a message to rabbitmq
and the code which is responsible for that part is as below:
package main
import (
"log"
"github.com/streadway/amqp"
)
func main() {
conn, amqError := amqp.Dial("amqp://localhost:5672/")
if amqError != nil {
panic(amqError)
}
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
q, err := ch.QueueDeclare(
"default", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
body := "{ \"body\":\"Hello...\", \"pattern\":\"test\", \"age\":\"20\"}"
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
},
)
failOnError(err, "Failed to publish a message")
}
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
And the Nestjs
part that is consuming the message is as:
import { Controller } from '@nestjs/common';
import { Ctx, EventPattern, Payload, RmqContext } from '@nestjs/microservices';
@Controller()
export class AppController {
constructor() { }
@EventPattern("test")
getEventMessage(@Payload() data: any, @Ctx() context: RmqContext) {
console.log("data is -> ", data) // always undefined
console.log(
"content of message is -> ",
JSON.parse(
context.getMessage().content.toString() // from buffer to string
)
)
}
}
Now the problem is that I can't get the message from data instead of parsing it from ctx
, also I need to send the message in go as json
without skipping double quotes like this "\""
答案1
得分: 1
以下是对你的问题的回答:
- 在 NextJS 的示例中,他们没有提供如何使用有效载荷数据的方法,而是说:
要访问原始的 RabbitMQ 消息(包括属性、字段和内容),请使用 RmqContext 的 getMessage() 方法
根据上述说明,你正在正确解析队列中的消息。
- 为了避免手动创建要发送的字符串体,你应该使用一个称为结构体的过程进行 json 编组,例如:
- 你应该创建一个包含要发送到队列的信息的结构体
- 对结构体进行编组并生成
[]byte
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}
func NewMessageQueue(body, pattern, age, data string) *MessageQueue {
return &MessageQueue{
Body: body,
Pattern: pattern,
Age: age,
Data: data,
}
}
func (m *MessageQueue) Marshal() ([]byte, error) {
bytes, err := json.Marshal(m)
if err != nil {
return nil, err
}
return bytes, err
}
func main() {
...
message := NewMessageQueue("Hello...", "test", "20", "data...")
// TODO: 检查错误
body, _ := message.Marshal()
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: body,
},
)
...
}
更新:
getEventMessage
方法中控制器接收的data
参数应该在 Golang 中作为 body 发送,以便由Nestjs
进行反序列化。这意味着结构应该如下所示:
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}
英文:
The following is the response to your questions:
- In the examples of NextJS they don't provide how to use the payload data, instead of it, they say:
> To access the original RabbitMQ message (with the properties, fields,
> and content), use the getMessage() method of the RmqContext
Given the above statement, you are parsing properly the message in the queue.
- Avoiding to do manually the body string to send, you should use a process called json Marhsal of struct, for example:
- You should create a struct that contains the information to send to queue
- Marshal struct and generates the
[]byte
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}
func NewMessageQueue(body, pattern, age string, data) *MessageQueue {
return &MessageQueue{
body, pattern, age, data
}
}
func (m *MessageQueue) Marshal() ([]byte, error) {
bytes, err := json.Marshal(m)
if err != nil {
return nil, err
}
return bytes, err
}
func main() {
...
message := NewMessageQueue("Hello...", "test", "20", "data...")
// TODO: check the error
body, _ := message.Marshal()
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: body,
},
)
...
}
Update:
- The
data
param received by controller ongetEventMessage
method, it should be sent on body from Golang to be deserialized byNestjs
. It means the structure should be the following:
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论