Disconnect user when they navigate away from page

72 views
Skip to first unread message

razor

unread,
Oct 13, 2010, 1:18:52 AM10/13/10
to cometd-users
Has anyone successfully figured out a way if to disconnect a user from
the comet server when they navigate away from a page?

The issue im having with is that when a user (lets say user-a) leaves
a chat room, all other users that are connected to that chat room has
no way of knowing that user-a has left.

I've been using the unload window handler where itll call a method to
publish current user's id to notify everyone who that user id has
disconnected. However, i find that this approach is not reliable.

Im all out of ideas, any help?

Thanks

Simone Bordet

unread,
Oct 13, 2010, 3:19:24 AM10/13/10
to cometd...@googlegroups.com
Hi,

On Wed, Oct 13, 2010 at 07:18, razor <ryann...@gmail.com> wrote:
> Has anyone successfully figured out a way if to disconnect a user from
> the comet server when they navigate away from a page?
>
> The issue im having with is that when a user (lets say user-a) leaves
> a chat room, all other users that are connected to that chat room has
> no way of knowing that user-a has left.

You can register a remove listener.
When the server expires user-a, you can send a message on the
membership channel, so all other users are notified that user-a left.

What CometD version ?

Simon
--
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz

razor

unread,
Oct 13, 2010, 3:54:53 AM10/13/10
to cometd-users
Hi Simon,

Thanks for the response.

Im currently using CometD 2.0 / jQuery and jetty7

Do i register removeListener right after "addListener" as it's written
the documentation (http://cometd.org/documentation/cometd-javascript/
subscription) ? Im a bit confused on how this function should
behave. I assumed 'removeListener' is to be called if you no longer
would like to listen to any of the subscribed events.

Thanks once again.

Ryan

On Oct 13, 12:19 am, Simone Bordet <simone.bor...@gmail.com> wrote:
> Hi,
>
> On Wed, Oct 13, 2010 at 07:18, razor <ryannel...@gmail.com> wrote:
> > Has anyone successfully figured out a way if to disconnect a user from
> > the comet server when they navigate away from a page?
>
> > The issue im having with is that when a user (lets say user-a) leaves
> > a chat room, all other users that are connected to that chat room has
> > no way of knowing that user-a has left.
>
> You can register a remove listener.
> When the server expires user-a, you can send a message on the
> membership channel, so all other users are notified that user-a left.
>
> What CometD version ?
>
> Simon
> --http://bordet.blogspot.com

Simone Bordet

unread,
Oct 13, 2010, 4:10:12 AM10/13/10
to cometd...@googlegroups.com
Hi,

On Wed, Oct 13, 2010 at 09:54, razor <ryann...@gmail.com> wrote:
> Hi Simon,
>
> Thanks for the response.
>
> Im currently using CometD 2.0 / jQuery and jetty7
>
> Do i register removeListener right after "addListener" as it's written
> the documentation (http://cometd.org/documentation/cometd-javascript/
> subscription) ?  Im a bit confused on how this function should
> behave.  I assumed 'removeListener' is to be called if you no longer
> would like to listen to any of the subscribed events.

No, a RemoveListener is a listener that gets called when the session expires.

See http://svn.cometd.org/tags/2.0.0/cometd-java/cometd-java-examples/src/main/java/org/cometd/examples/ChatService.java#handleMembership()

That method is called once when the sessions first register to the
chat room, and adds a RemoveListener to the session so that when it
expires it broadcast the members to other sessions.

Simon
--

Ryan Nelwan

unread,
Oct 13, 2010, 1:11:57 PM10/13/10
to cometd...@googlegroups.com
Thanks Simon, Ive got it to work now.  You are too awesome.

Ryan

--
You received this message because you are subscribed to the Google Groups "cometd-users" group.
To post to this group, send email to cometd...@googlegroups.com
To unsubscribe from this group, send email to cometd-users...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/cometd-users

Visit the CometD website at http://www.cometd.org

Simone Bordet

unread,
Feb 16, 2011, 7:08:38 AM2/16/11
to cometd...@googlegroups.com, agim...@gmail.com
Hi,

On Wed, Feb 16, 2011 at 12:31, agi <agim...@gmail.com> wrote:
> Hello everyone,
>
> I am also having problems with the client disconnect and I am hope you
> can help me out.:) I am using dojo 1.5.0 and CometD 1.1.1 on GlassFish
> and Oracle Weblogic 10.2 (the cometd implementation is wrapped with
> the atmosphere framework which enables it to run on any java server).

I do not think you need to wrap CometD into atmosphere as we have
reports working in GlassFish without it.
Anyway, if it works for you, fine.

> I have a BayeuxService that adds a RemoveListener to each client in my
> web application. The RemoveListener cleans up the client associated
> server side data when a client is removed/disconnected but the problem
> is that it doesn't get fired because the server obviously doesn't seem
> to be able to detect a disconnected client.

The server is able to detect a disconnected client, either by
receiving a disconnect message or by expiring clients it does not see
in a while after a configurable timeout.

> It gets triggered OK when
> I call dojox.cometd.disconnect(); from javascript on the page but it
> doesn't work when I put it in a window.onunload handler like that:
> window.onunload = function() {
>   dojox.cometd.disconnect();
> }

First, are you sure that the onunload function is called at all ? I
ask because often browsers are buggy on this.
Even if it's called, it's upon the browser to decide if allow further
HTTP requests (the disconnect message) from a page the browser knows
it will be dismissed.
I do not think there is a clear specification about unload handlers
(what they can do and what they cannot), but I'll be glad to read it
if anyone has a pointer.

You can try a synchronous disconnect by calling:

window.onunload = function() {
dojox.cometd.disconnect(true);
}

but that's only a hint, since it's not supported by certain transports
and the browser can still ignore it.
See http://bugs.cometd.org/browse/COMETD-67 and
http://bugs.cometd.org/browse/COMETD-186 for further discussion.

While it's ok to attempt to disconnect gracefully, the server side
application code should not expect it but rely on the expiration that
will kick in after the timeout.

agi

unread,
Feb 16, 2011, 8:15:44 AM2/16/11
to cometd-users
Hey,

thanks for the quick reply.

> I do not think you need to wrap CometD into atmosphere as we have
> reports working in GlassFish without it.
> Anyway, if it works for you, fine.

I know CometD works on GlassFish out of the box, I am not using
atmosphere just for fun.:) It is because it enables me to setup my web
application and deploy it on Glassfish and Weblogic without any
modifications. For testing purposes I use GlassFish but we use
Weblogic in a production environment, so such a wrapper framework is a
necessity.

> The server is able to detect a disconnected client, either by
> receiving a disconnect message or by expiring clients it does not see
> in a while after a configurable timeout.

That doesn't seem to be true in my case. Which parameters should I use
to configure such behaviour? At the moment am using the following init
parameters in web.xml:
<init-param>
<param-name>timeout</param-name>
<param-value>60000</param-value>
</init-param>
<init-param>
<param-name>maxInterval</param-name>
<param-value>10000</param-value>
</init-param>

> First, are you sure that the onunload function is called at all ? I
> ask because often browsers are buggy on this.
> Even if it's called, it's upon the browser to decide if allow further
> HTTP requests (the disconnect message) from a page the browser knows
> it will be dismissed.
> I do not think there is a clear specification about unload handlers
> (what they can do and what they cannot), but I'll be glad to read it
> if anyone has a pointer.
>
> You can try a synchronous disconnect by calling:
>
> window.onunload = function() {
>     dojox.cometd.disconnect(true);
>
> }
>
> but that's only a hint, since it's not supported by certain transports
> and the browser can still ignore it.

The window.onunload handler gets triggeres all right, but the
disconnect isn't successful (I will try to place a server side
listener on the /meta/disconnect channel to confirm this). Also no
success using disconnect(true).

> Seehttp://bugs.cometd.org/browse/COMETD-67andhttp://bugs.cometd.org/browse/COMETD-186for further discussion.
>

I will look into that. Thank you very much.

> While it's ok to attempt to disconnect gracefully, the server side
> application code should not expect it but rely on the expiration that
> will kick in after the timeout.

Exactly when should a client be automatically disconnected/removed?
"maxInterval" ms after the timeout (in my case 10s after an
unsuccessful reconnect)? Maybe the automatic client removal isn't
working because of a problem with the atmosphere framework, I will ask
the guys a atmosphere about that...

Thanks again.

Marko

Simone Bordet

unread,
Feb 16, 2011, 9:29:22 AM2/16/11
to cometd...@googlegroups.com
Hi,

On Wed, Feb 16, 2011 at 14:15, agi <agim...@gmail.com> wrote:
> I know CometD works on GlassFish out of the box, I am not using
> atmosphere just for fun.:) It is because it enables me to setup my web
> application and deploy it on Glassfish and Weblogic without any
> modifications. For testing purposes I use GlassFish but we use
> Weblogic in a production environment, so such a wrapper framework is a
> necessity.

Oh, ok. So it's needed by WebLogic ?
I seems to recall having others using WebLogic without Atmosphere, but
as I said, fine.
It's just for the record in case someone browses the mail archives.

>> The server is able to detect a disconnected client, either by
>> receiving a disconnect message or by expiring clients it does not see
>> in a while after a configurable timeout.
>
> That doesn't seem to be true in my case. Which parameters should I use
> to configure such behaviour? At the moment am using the following init
> parameters in web.xml:
> <init-param>
>    <param-name>timeout</param-name>
>    <param-value>60000</param-value>
> </init-param>
> <init-param>
>    <param-name>maxInterval</param-name>
>    <param-value>10000</param-value>
> </init-param>

It's "maxInterval", here at 10 seconds.
After 10 seconds that a connect is not seen from a client, the server
expires the client (10 seconds + the sweeper delay, which is at most 2
seconds IIRC).

> Exactly when should a client be automatically disconnected/removed?
> "maxInterval" ms after the timeout (in my case 10s after an
> unsuccessful reconnect)?

Correct.

> Maybe the automatic client removal isn't
> working because of a problem with the atmosphere framework, I will ask
> the guys a atmosphere about that...

Let us know if that's the case.

agi

unread,
Feb 16, 2011, 9:54:30 AM2/16/11
to cometd-users
I have found the solution for the client side problem (onunload not
properly calling disconnect()) in this thread:
http://groups.google.com/group/cometd-users/browse_thread/thread/8ea465b3d65bf73a.
Before the actual dojox.cometd.disconnect() call I was unsubscribing
from all subscribed channels, with that removed disconnect now works
fine. I don't know for sure, but if I don't do the unsubscribes this
should not cause any additional problems. If the client gets removed
anyway, I assume it doesn't matter if it has any existing
subscriptions, they also get removed? Correct me if I am wrong.

However I still have to resolve the issue regarding the broken
detection of disconnected clients on the server...

Simone Bordet

unread,
Feb 16, 2011, 10:08:39 AM2/16/11
to cometd...@googlegroups.com
Hi,

On Wed, Feb 16, 2011 at 15:54, agi <agim...@gmail.com> wrote:
> However I still have to resolve the issue regarding the broken
> detection of disconnected clients on the server...

Be sure on server side you have a System.out that prints when a
Session is removed (need to implement ServerSession.RemoveListener),
then open your application in Firefox, allow CometD to connect, then
click File/Work Offline.
Go to the server console and wait for the printout after maxInterval.

agi

unread,
Feb 18, 2011, 6:03:24 AM2/18/11
to cometd-users
I have put together a simple example of a javascript client that
connects to cometd and publishes a string to channel "/test". On the
server side I've added a BayeuxService to this channel which adds a
RemoveListener for every new client. I didn't use atmosphere, just
CometdD 1.1.2 and dojo 1.5.0 (with the dojox/cometd directory from
CometD 1.1.2). The RemoveListener seems to be triggering on timeout
but not in every case. If I open a comet connection with only one
client and close it (dojox.cometd.disconnect() is not called) I can
wait for a timeout indefinitely, it never happens. But as soon as I
try to access the sample web application again - without openning
another comet connection - the timeout happens. It is a very weird
dependancy.:) I'll be happy to share the example if you want to have a
look at it.

Simone Bordet

unread,
Feb 18, 2011, 6:26:29 AM2/18/11
to cometd...@googlegroups.com, agi
Hi,

Please upgrade to CometD 1.1.3, and see if the problem remains.
If so, then please file a bug at http://bugs.cometd.org with the
reproducible test case attached with exact steps to reproduce the
problem.

agi

unread,
Feb 18, 2011, 7:31:57 AM2/18/11
to cometd-users
Hey,

the freezing up happens also with CometD 1.1.2. I am not saying I am
not doing something wrong, it could also be that my code is faulty but
I am just sending a string to a channel and then eventually
disconnecting, I am not sure how I could mess something up with such a
simple test case.

Marko

Simone Bordet

unread,
Feb 18, 2011, 7:33:39 AM2/18/11
to cometd...@googlegroups.com, agi
Hi,

Could it be that the servlet container that you're using is not Jetty,
and that it is a buggy or misconfigured one ?

agi

unread,
Feb 18, 2011, 7:35:16 AM2/18/11
to cometd-users
Hey,

>Hi,
>
>> I have tried CometD 1.1.3 and it does do the timeouts but after the
>> first comet connection was established the server becomes very
>> unresponsive and eventually throws this exception:
>> java.lang.IllegalStateException: Asynchronous dispatch already in
>> progress, must call ServletRequest.startAsync first
>> at
>> org.apache.catalina.connector.AsyncContextImpl.dispatch(AsyncContextImpl.java:

>Now I have doubts you have configured everything correctly to work in Tomcat.
>Please try with Jetty first. If it works there, I can help (up to a
>certain point) to run CometD in Tomcat, but I cannot shield you from
>Tomcat bugs.

I am using GlassFish v3.

Simone Bordet

unread,
Feb 18, 2011, 7:39:46 AM2/18/11
to cometd...@googlegroups.com, agi
Hi,

On Fri, Feb 18, 2011 at 13:35, agi <agim...@gmail.com> wrote:
> I am using GlassFish v3.

What precise version ?
GF was known to have bugs in handling asynchronous requests.
Please search the lists archives for others that had problems and
reported that certain GF version actually worked fine.

agi

unread,
Feb 18, 2011, 7:46:03 AM2/18/11
to cometd-users
Hello,

On Feb 18, 1:33 pm, Simone Bordet <simone.bor...@gmail.com> wrote:
> Hi,
>
> Could it be that the servlet container that you're using is not Jetty,
> and that it is a buggy or misconfigured one ?
>
I am using Servlet 3.0 on GlassFish v3, here is the content of my
web.xml:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>Cometd Servlet</servlet-name>
<servlet-
class>org.cometd.server.continuation.ContinuationCometdServlet</
servlet-class>
<!-- CometdServlet's long-poll timeout set to 1 minute -->
<init-param>
<param-name>timeout</param-name>
<param-value>60000</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet>
<servlet-name>ConfigurationServlet</servlet-name>
<servlet-class>ConfigurationServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Cometd Servlet</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ConfigurationServlet</servlet-name>
<url-pattern>/Configuration</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

If I don't use Servlet 3.0, I get the following exception when I try
to connect to cometd:
WARNING: StandardWrapperValve[Cometd Servlet]: PWC1406:
Servlet.service() for servlet Cometd Servlet threw exception
java.lang.IllegalStateException: Request is within the scope of a
filter or servlet that does not support asynchronous operations
at
org.apache.catalina.connector.Request.startAsync(Request.java:3597)
at
org.apache.catalina.connector.Request.startAsync(Request.java:3549)
at
org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:
1039)
at
org.eclipse.jetty.continuation.Servlet3Continuation.suspend(Servlet3Continuation.java:
184)
at
org.cometd.server.continuation.ContinuationCometdServlet.service(ContinuationCometdServlet.java:
200)
at
org.cometd.server.AbstractCometdServlet.service(AbstractCometdServlet.java:
258)
at
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:
1523)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
279)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
188)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:
97)
at
com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:
85)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
185)
at
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:
332)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
233)
at
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:
165)
at
com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:
791)
at
com.sun.grizzly.comet.CometEngine.executeServlet(CometEngine.java:473)
at com.sun.grizzly.comet.CometEngine.handle(CometEngine.java:
341)
at
com.sun.grizzly.comet.CometAsyncFilter.doFilter(CometAsyncFilter.java:
84)
at
com.sun.grizzly.arp.DefaultAsyncExecutor.invokeFilters(DefaultAsyncExecutor.java:
161)
at
com.sun.grizzly.arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:
137)
at
com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:
88)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:189)
at com.sun.grizzly.util.AbstractThreadPool
$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool
$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)

agi

unread,
Feb 18, 2011, 7:51:38 AM2/18/11
to cometd-users
Hello,

On Feb 18, 1:39 pm, Simone Bordet <simone.bor...@gmail.com> wrote:
> Hi,
>
> What precise version ?
> GF was known to have bugs in handling asynchronous requests.
> Please search the lists archives for others that had problems and
> reported that certain GF version actually worked fine.
>

GlassFish v3 (build 74.2). Thank for the tip, I will look it up.

Marko
Reply all
Reply to author
Forward
0 new messages