在grails控制器中使用JMS消息

时间:2014-03-02 07:46:35

标签: grails jms

我有一个简单的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应用程序,如果答案看起来很明显,请原谅我

2 个答案:

答案 0 :(得分:1)

在这种情况下我更喜欢使用websockets。查看http://grails.org/plugin/atmosphere

否则我建议您将数据推送到数据库并从控制器检查数据库,而不是检查服务。

既然你在工作氛围方面遇到了问题,我会试着解释一下我是如何运作的。

  1. 安装了grails氛围插件以获取依赖项。
  2. 将jquery.atmosphere.js添加到前端。
  3. 添加了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
    
    }
    

    }

  4. 添加以下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"
    }
}

我不确定如何将更新推送到浏览器或刷新页面(如何取消任务),但在完成后会发布更新。