C# RabbitMQ消息发布方法 C#如何使用EasyNetQ发送消息

5次阅读

easynetq发布消息前必须确保消费者已就绪,首次bus.subscribe()才创建队列并绑定交换机;先发后订会导致消息被丢弃,除非显式声明持久化队列。

C# RabbitMQ消息发布方法 C#如何使用EasyNetQ发送消息

EasyNetQ发布消息前必须确保消费者已就绪

很多人一上来就跑 bus.Publish(),控制台没输出、消息“消失”了——其实不是丢了,是没人收。EasyNetQ的订阅是动态绑定队列的,**首次 bus.Subscribe() 时才会创建队列并绑定交换机**。如果先发后订,消息默认被丢弃(除非启用了持久化+队列存在且设置了 autoDelete=false)。

  • 务必先启动 Consumer 程序,看到控制台打印 “Subscribed to …” 再运行 Publisher
  • 开发阶段建议在 Consumer 中加 console.ReadLine() 防止进程退出,避免队列被自动删除
  • 若需“先发后收”,得显式声明持久化队列:bus.Advanced.QueueDeclare("my.queue", durable: true)

发送字符串或自定义对象?序列化是关键门槛

EasyNetQ 默认用 json 序列化,但如果你直接 bus.Publish("hello"),它会把字符串当成原始字节发出去,Consumer 收到的是 byte[],不是 String —— 这就是为什么常见报错 Cannot deserialize the current JSON Array 或黑屏无反应。

  • 发送简单值类型(如 stringint):显式指定泛型bus.Publish<string>("hello")</string>
  • 发送自定义类(如 TextMessage):类必须有 public 无参构造函数,属性为 public get/set;发送时写 bus.Publish(new TextMessage { Text = "hi" })
  • 切勿手动 JsonConvert.SerializeObject() 后再 Publish,EasyNetQ 会二次序列化导致嵌套

连接字符串写错、VirtualHost 权限不足,连不上就发不出

最常见的连接失败不是端口不通,而是 virtualHost 拼写错误或权限未分配。rabbitmq 默认 virtual host 是 /,但 EasyNetQ 解析时会把 / 当作路径分隔符,必须 URL 编码为 %2F

  • 正确写法:"host=localhost;virtualHost=%2F;username=guest;password=guest"
  • 如果用了非默认 vhost(如 myapp),先登录 http://localhost:15672 → Admin → Virtual Hosts → Add a new virtual host,再给用户分配权限
  • 测试连接是否有效:在 RabbitHutch.CreateBus(...) 后加一句 bus?.Advanced.ExchangeDeclare("test.ex", "direct");,抛异常即说明连不上

异步发布要注意 Task 未 await 导致程序提前退出

bus.PublishAsync() 返回 Task,但很多示例里只写 .ContinueWith() 就不管了。线程结束,进程退出,Task 根本没机会执行。

  • 控制台程序中,改用 await bus.PublishAsync(msg),并在 Main 方法上加 async(.NET Core 5+ 支持 async Main)
  • 若无法改 async Main,至少加 bus.PublishAsync(msg).Wait() 强制同步等待(仅限开发调试,生产慎用)
  • 注意:PublishAsync 不保证消息已落盘,只表示已发到 RabbitMQ TCP 连接缓冲区;要确认投递成功,需启用 publisher confirms(需服务端配置 + bus.Advanced.Publish 底层调用)

真正卡住人的往往不是语法,而是那句没看到的提示:“Subscribed to ‘xxx’ on exchange ‘xxx’”。盯着日志看,比翻文档快得多。

text=ZqhQzanResources