我已经浏览了rabbitMQ插件的优秀文档。但是,我仍然对一些事情感到困惑。
方案
我的应用程序将从用户上传文件,对文件执行各种操作,并相应地在域对象上设置某些属性。其中一些工作可能是劳动密集型的,所以我使用的是队列。我设想请求排队,消费者从队列中获取请求并使用它们。
问题
我想在队列中存储域对象。我是这样做的:rabbitSend 'myqueue', colorObj
。 colorObj
是域类Color
的对象
但是,在ColorService
handleMessage(...)
中,当我从队列中获取项目时,该项目的类型不是Color
。请注意,在rabbitMQ仪表板上,我可以看到正在插入队列中的项目,因此config.groovy
中的队列启动正常(我正在使用amq.direct
)
handleMessage
不需要实例化。即使我不调用ColorService
,它仍会自行执行handleMessage
。这是正常行为吗?以下是代码:
控制器
Color colorObj = colorService.newRequest(params, request.getFile('color.filename')
if (colorObj.validate)
rabbitSend 'myqueue', colorObj
...
服务
class ColorService {
static rabbitQueue = 'myqueue'
void handleMessage(message) {
println "came in message: " + message instanceof Color //this prints false
}
}
答案 0 :(得分:2)
正如Tim所说,如果你能够通过传递最简单的域实例ID。在邮件传输过程中,您确实需要注意对域实例的更改。
或者,如果它是您感兴趣的数据,我更喜欢使用类似
之类的对象将对象序列化为JSONrabbitSend 'myqueue', (colorObj as JSON).toString()
当然,现在你的监听器正在接收一个字符串,所以你必须将其转换回来:
void handleMessage(String message) {
def color = new Color(JSON.parse(message))
println "came in message: " + color instanceof Color
}
GPRABBITMQ-15 issue上就此进行了一些讨论。
答案 1 :(得分:1)
如图所示in the documentation,您可以发送String
或Map
为什么不发送域对象的id
:
rabbitSend 'myqueue', colorObj.id
然后,在处理邮件时将其重新加载:
void handleMessage(message) {
println "Got ${Color.get( message )}"
}
或者,如果在处理消息之前不需要域对象,请发送所有必需数据的映射,并让服务在成功处理后创建域对象?