Отключение сокетов атмосферы в Grails

Я пишу приложение Grails, которое использует плагин Atmosphere. Соединение работает, но каждый раз, когда я обновляю страницу в браузере, я вижу, что мой веб-сервер добавляет новый поток Daemon, который впоследствии никогда не выпускается.

После того, как количество потоков достигает 200, веб-сервер зависает.

Кажется, нет документации, объясняющей, как правильно обрабатывать ресурсы (отключать) с помощью плагина Atmosphere?

Мой клиентский код делает это:

var connectedEndpoint = null;

$(function() 
{
function callback(response)
{
    if (response.transport != 'polling' && response.state != 'connected' && response.state != 'closed') {
        if (response.status == 200) {
            eval(response.responseBody);
        }
    }
}

$.atmosphere.subscribe('${resource(dir: '/atmosphere/channel')}', callback, $.atmosphere.request = {transport: 'streaming'});
connectedEndpoint = $.atmosphere.response;

});

$(window).unload( function () 
{ 
    $.atmosphere.unsubscribe();
    connectedEndpoint = null;
});

Я использую обработчик атмосферы на стороне сервера;

package demo

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.atmosphere.cpr.AtmosphereHandler
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;

class DemoController implements AtmosphereHandler<HttpServletRequest, HttpServletResponse> {

@Override
public void destroy() {
    println "destroy"
}

@Override
public void onRequest( AtmosphereResource<HttpServletRequest, HttpServletResponse> event) throws IOException 
{
    event.suspend()
}

@Override
public void onStateChange( AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) throws IOException 
{
    if (event.isSuspended()) 
    {
        event.resource.response.writer.with {
            def message = event.message
            write "set${message.paramName}(\"${message.id}\",\"${message.value}\");"
            flush()
        }
    }
}
}

Функция destroy обработчика никогда не вызывается!

На следующем рисунке показано, что у меня запущено 23 потока. Когда я запускаю свое приложение, их около 6, и они добавляются каждый раз, когда я нажимаю F5! Если я отключу атмосферу, новые темы не будут добавлены, поэтому эта проблема связана с атмосферой. (Я использую SpringSource Tools Suite в Windows7).

Daemon threads

Если решение не является тривиальным, я был бы признателен за подробные пошаговые инструкции или пример.

ОБНОВЛЕНИЕ: после развертывания в Tomcat каждые 20 секунд возникают следующие ошибки:

Apr 02, 2012 2:35:15 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Apr 02, 2012 2:35:16 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Apr 02, 2012 2:35:17 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Apr 02, 2012 2:35:17 PM org.apache.coyote.http11.Http11AprProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 02, 2012 2:35:17 PM org.apache.coyote.ajp.AjpAprProtocol start
INFO: Starting Coyote AJP/1.3 on ajp-8009
Apr 02, 2012 2:35:17 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 11401 ms
2012-04-02 14:41:17,122 [http-8080-39] ERROR cpr.AsynchronousProcessor  - failed
 to timeout resource AtmosphereResourceImpl{, hasCode-1035775543,
 action=org.atmosphere.cpr.AtmosphereServlet$Action@f2718e,
 broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
 cometSupport=org.atmosphere.container.TomcatCometSupport@107fff7,
 serializer=null,
 isInScope=true,
 useWriter=true,
 listeners=[]}
2012-04-02 14:42:15,034 [http-8080-69] ERROR cpr.AsynchronousProcessor  - failed
 to timeout resource AtmosphereResourceImpl{, hasCode-58082012,
 action=org.atmosphere.cpr.AtmosphereServlet$Action@ae4dd4,
 broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
 cometSupport=org.atmosphere.container.TomcatCometSupport@107fff7,
 serializer=null,
 isInScope=true,
 useWriter=true,
 listeners=[]}
2012-04-02 14:44:41,159 [http-8080-13] ERROR cpr.AsynchronousProcessor  - failed
 to timeout resource AtmosphereResourceImpl{, hasCode648226529,
 action=org.atmosphere.cpr.AtmosphereServlet$Action@507e61,
 broadcaster=org.atmosphere.cpr.DefaultBroadcaster,
 cometSupport=org.atmosphere.container.TomcatCometSupport@107fff7,
 serializer=null,
 isInScope=true,
 useWriter=true,
 listeners=[]}

 ....

person conceptacid    schedule 12.03.2012    source источник


Ответы (2)


Какой веб-сервер вы используете? Похоже, веб-сервер не обнаруживает, когда браузер закрывает соединение. Вы можете добавить в web.xml следующий детектор тайм-аута

org.atmosphere.cpr.CometSupport.maxInactiveActivity=30000 //30 seconds
person jfarcand    schedule 12.03.2012
comment
К сожалению, это не работает: No such property: maxInactiveActivity for class: org.atmosphere.cpr.CometSupport - person conceptacid; 13.03.2012

Я считаю, что ваша проблема связана с событием разгрузки. "$(окно).выгрузить". Я знаю, по крайней мере, в хроме вы ничего не можете сделать в событиях выгрузки или перед выгрузкой. поэтому ваш браузер, вероятно, никогда не запускает unsubscribe().

если вы посмотрите на пример Atmospheres jquery pubsub, вы увидите отмену подписки перед подключением, function connect() { unsubscribe(); ...

вы можете закодировать цикл для проверки вещателей, отправляя незначительные данные для периодической проверки вещателей, если они не очищаются. Мне нужно больше исследовать атмосферу и надеяться на лучшее решение. надеюсь, вы сможете очистить потоки, когда новое соединение создается из обновления, и позволить старым истекать вместе с сеансом, когда пользователь уходит.

person ChrisThompson    schedule 23.04.2012
comment
Спасибо за внимание! Я не думаю, что это отказ от подписки: я пытался явно вызвать отказ от подписки, нажав кнопку. Я думаю, что проблема каким-то образом связана со средой Grails + AtmospherePlugin, работающей в SpringSource Tool Suite с сервлетом Tomcat, или, по крайней мере, связана с Grails + Tomcat. Позже я решил обойти эту проблему, просто изменив всю структуру моего веб-сайта на ajax (к счастью, это была всего лишь небольшая демонстрация, а не реальный продукт), но в конце концов я попытался использовать Jetty 8 и мониторю веб-ресурсы, используя консоль jmx - проблем не наблюдалось! - person conceptacid; 24.04.2012
comment
У нас точно такая же проблема в комбинации Wicket+Atmosphere+Tomcat - так что это похоже на Tomcat + Atmosphere (настройки коннекторов по умолчанию - BlockingIOCometSupport) - person Michal Bernhard; 26.02.2014