我有一个简单的JMS设置。请参阅以下代码:
class ProcessingService{
def jmsService
def theMethod(){
jmsService.send(service:'listening', value);
}
}
@Transactional
static scope = "session"
class ListeningService {
static expose = ['jms']
private int value;
def onMessage(message) {
value = message;
println "Completed ${message}"
}
int getValue(){
return value;
}
}
我的问题是如何使用从控制器发送的消息?
目前我有以下代码,但我不确定这是否正确,因为服务设计为无状态:
class ConsumingController{
def listeningService
def method(){
while(notTimeout){
log.info(listeningService.getValue())
}
}
}
这是我的第一个jms应用程序,如果答案看起来很明显,请原谅我
答案 0 :(得分:1)
在这种情况下我更喜欢使用websockets。查看http://grails.org/plugin/atmosphere
否则我建议您将数据推送到数据库并从控制器检查数据库,而不是检查服务。
既然你在工作氛围方面遇到了问题,我会试着解释一下我是如何运作的。
添加了AtmosphereService类(查看sendData方法)
类AtmosphereService实现了AtmosphereHandler {
static exposes = ['jms']
static transactional = false
static atmosphere = [mapping: '/atmosphere']
public void sendData(int value, long userId){
Map result = [value: value];
String broadcastChannel = "/$userId/value";
Broadcaster broadcaster = BroadcasterFactory.default.lookup(broadcastChannel, true);
broadcaster.broadcast((result as JSON) as String);
}
public void onRequest(AtmosphereResource resource) throws IOException {
try {
AtmosphereRequest req = resource.request
if (req.method.equalsIgnoreCase("GET")) {
resource.broadcaster = BroadcasterFactory.default.lookup(req.pathInfo, true);
resource.suspend();
} else if (req.method.equalsIgnoreCase("POST")) {
String stuff = req.reader.readLine().trim()
resource.broadcaster = BroadcasterFactory.default.lookup(req.pathInfo, true);
resource.broadcaster.broadcast(stuff);
}
} catch (Exception e) {
log.error("Error in Atmosphere.onRequest", e);
}
}
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
AtmosphereResource r = event.resource
AtmosphereResponse res = r.response
try {
if (event.isSuspended()) {
String body = (event.message) as String;
res.writer.write( body );
switch (r.transport()) {
case TRANSPORT.JSONP:
case TRANSPORT.LONG_POLLING:
event.resource.resume()
break
default:
res.writer.flush()
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("ERROR in onStateChange", e);
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
添加以下js代码以侦听频道“/ $ userId / value”(查看request.onMessage处理程序)
var contentType = "application/json";
var userId = 12312;
var logLevel = 'debug';
var shared = 'true';
var transport = 'websocket';
var fallbackTransport = 'long-polling';
var socket = $.atmosphere;
var partialUpdateRequest=null;
var atmosphereUrl = BASE_HREF+'/atmosphere';
var request = { url: atmosphereUrl +"/"+userId+"/value",
contentType : contentType,
logLevel : logLevel,
shared : shared,
transport : transport,
fallbackTransport: fallbackTransport
};
request.onMessage = function (response) {
var message = response.responseBody;
try {
var json = jQuery.parseJSON(message);
// do your stuff here.
}catch (e) {
//return;
}
};
socket.subscribe(request);
答案 1 :(得分:0)
我为我工作的一个替代方案是使用事件api使用grails-platform-core插件。
http://grailsrocks.github.io/grails-platform-core/
和
http://grails.org/plugin/platform-core
以下是我目前正在做的事情:
class ExcelService{
def processMethod(){
while(not done){
//do some processing
event("excelUpdates", completed)
}
}
}
//the controller
class ExcelProcessorService {
@grails.events.Listener
def excelUpdates(Float completed){
println "${completed}% of excel processing task completed"
}
}
我不确定如何将更新推送到浏览器或刷新页面(如何取消任务),但在完成后会发布更新。