Open GoogleCodeExporter opened 9 years ago
I guess your problem is that you can't have two different sessions within one
browser when using cookies.
I would suggest to try it with e.g. Chrome + FF or to disable cookies at all.
Original comment by mmm1...@gmx.net
on 13 Aug 2011 at 7:23
I started looking into this same issue. I have curiously found that when
putting a breakpoint on EventSourceHandler.onOpen(...) that a second tab hits
this breakpoint repeatedly. I have also seen the doComet repeatedly invoked. It
seems that opening a second tab causes a spin of an unbounded number of
connections.
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 12:23
Actually, the client sees that expectingDisconnection is true and it
reconnects.... over and over
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 12:26
Docs state "When your application returns from the doComet the Comet response
and HTTP response is suspended so that you can continue to write messages to it
asynchronously from other threads.", however, this is not what happens,
EventSourceCometServletResponse.initiate calls tryTerminate which causes the
client to disconnect.
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 12:53
When new connections come in from the same browser, the session is shared and
that is incompatible with the assumption in this comment:
// This must be as the last step of initialise because after this
// response is set in the session
// it must be fully setup as it can be immediately terminated by the
// next response
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 4:57
The best solution may be to use the UrlRewriteFilter and create a session per
tab.
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 5:24
Here's a path that gwteventservice uses to solve this problem
http://code.google.com/p/gwteventservice/issues/detail?id=15
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 6:30
This may have worked around the issue with the following in the servlet that
uses a custom client ID and a comet session per client, even if the http
session is shared.
private static class CustomSession extends SessionWrapper {
public CustomSession (HttpSession delegate, String prefix) {
super (delegate);
this.prefix = prefix;
}
@Override
public Object getAttribute (String name) {
return super.getAttribute (this.prefix + "_" + name);
}
@Override
public Enumeration<String> getAttributeNames () {
List<String> names = new ArrayList<String> ();
for (@SuppressWarnings("unchecked")
Enumeration<String> e = super.getAttributeNames (); e.hasMoreElements (); ) {
String name = e.nextElement ();
if (name.startsWith (this.prefix)) {
names.add (name);
}
}
final Iterator<String> i = names.iterator ();
return new Enumeration<String> () {
@Override
public boolean hasMoreElements () {
return i.hasNext ();
}
@Override
public String nextElement () {
return i.next ();
}
};
}
@Override
public void removeAttribute (String name) {
super.removeAttribute (this.prefix + "_" + name);
}
private String prefix;
}
private class CustomSessionRequest extends HttpServletRequestWrapper {
public CustomSessionRequest (HttpServletRequest delegate) {
super (delegate);
}
@Override
public HttpSession getSession (boolean create) {
HttpSession session = super.getSession (create);
if (null == session && !create) {
return null;
}
return new CustomSession (session, this.getPathInfo ());
}
}
@Override
protected void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet (new CustomSessionRequest (request), response);
}
The following in the client:
CometClient client = new CometClient (GWT.getModuleBaseURL() + "comet" + "/" +
Math.random (), (CometSerializer) GWT.create (ServerEventSerializer.class),
listener);
client.start ();
And the following path in web.xml:
<url-pattern>/comet/*</url-pattern>
Original comment by eric.woo...@gmail.com
on 10 Feb 2012 at 11:09
@Eric
private static class CustomSession extends SessionWrapper
I can't get which SessionWrapper class are you referring to
??
thanks for the code, anyway!
Original comment by ipliss...@gmail.com
on 16 Feb 2012 at 1:21
I wrote a SessionWrapper that implements javax.servlet.http.HttpSession
Original comment by eric.woo...@gmail.com
on 16 Feb 2012 at 3:51
I tried your code with the following SessionWrapper, but isn't working yet.
Same exceptions and same environment of the OP, but my problem arises when I
REFRESH the host page.
public class SessionWrapper implements HttpSession {
private ConcurrentHashMap<String, Object> attributes;
private HttpSession wrapped;
public SessionWrapper(HttpSession session){
this.wrapped = session;
this.attributes = new ConcurrentHashMap<String, Object>();
}
@Override
public Object getAttribute(String arg0) {
if (this.attributes.keySet().contains(arg0))
return this.attributes.get(arg0);
return null;
}
@Override
public Enumeration<String> getAttributeNames() {
return this.attributes.keys();
}
@Override
public long getCreationTime() {
return this.wrapped.getCreationTime();
}
@Override
public String getId() {
return this.wrapped.getId();
}
@Override
public long getLastAccessedTime() {
return this.wrapped.getLastAccessedTime();
}
@Override
public int getMaxInactiveInterval() {
return this.wrapped.getMaxInactiveInterval();
}
@Override
public ServletContext getServletContext() {
return this.wrapped.getServletContext();
}
@Override
@Deprecated
public HttpSessionContext getSessionContext() {
return this.wrapped.getSessionContext();
}
@Override
@Deprecated
public Object getValue(String arg0) {
return this.wrapped.getValue(arg0);
}
@Override
@Deprecated
public String[] getValueNames() {
return this.wrapped.getValueNames();
}
@Override
public void invalidate() {
this.wrapped.invalidate();
this.attributes.clear();
}
@Override
public boolean isNew() {
return this.wrapped.isNew();
}
@Override
@Deprecated
public void putValue(String arg0, Object arg1) {
this.wrapped.putValue(arg0, arg1);
}
@Override
public void removeAttribute(String arg0) {
if (this.attributes.keySet().contains(arg0))
this.attributes.remove(arg0);
}
@Override
@Deprecated
public void removeValue(String arg0) {
this.wrapped.removeValue(arg0);
}
@Override
public void setAttribute(String arg0, Object arg1) {
this.attributes.put(arg0, arg1);
}
@Override
public void setMaxInactiveInterval(int arg0) {
this.wrapped.setMaxInactiveInterval(arg0);
}
}
Original comment by ipliss...@gmail.com
on 17 Feb 2012 at 3:04
My session wrapper didn't augment the attribute list. It was simply a way to
have CustomSession prefix each attribute with the client ID. You need to store
the attributes in the original session. Otherwise, they are going to get
lost/separated with each doComet.
public class SessionWrapper implements HttpSession {
public SessionWrapper (HttpSession delegate) {
this.delegate = delegate;
}
public Object getAttribute (String arg0) {
return delegate.getAttribute (arg0);
}
public Enumeration getAttributeNames () {
return delegate.getAttributeNames ();
}
public long getCreationTime () {
return delegate.getCreationTime ();
}
public String getId () {
return delegate.getId ();
}
public long getLastAccessedTime () {
return delegate.getLastAccessedTime ();
}
public int getMaxInactiveInterval () {
return delegate.getMaxInactiveInterval ();
}
public ServletContext getServletContext () {
return delegate.getServletContext ();
}
public HttpSessionContext getSessionContext () {
return delegate.getSessionContext ();
}
public Object getValue (String arg0) {
return delegate.getValue (arg0);
}
public String[] getValueNames () {
return delegate.getValueNames ();
}
public void invalidate () {
delegate.invalidate ();
}
public boolean isNew () {
return delegate.isNew ();
}
public void putValue (String arg0, Object arg1) {
delegate.putValue (arg0, arg1);
}
public void removeAttribute (String arg0) {
delegate.removeAttribute (arg0);
}
public void removeValue (String arg0) {
delegate.removeValue (arg0);
}
public void setAttribute (String arg0, Object arg1) {
delegate.setAttribute (arg0, arg1);
}
public void setMaxInactiveInterval (int arg0) {
delegate.setMaxInactiveInterval (arg0);
}
private HttpSession delegate;
}
Original comment by eric.woo...@gmail.com
on 17 Feb 2012 at 4:21
ok tried and your method works very fine opening multiple tabs!
the evil IOException is still thrown when i REFRESH the page, but maybe is
another kind of issue
Original comment by ipliss...@gmail.com
on 17 Feb 2012 at 9:43
The heartbeat failing is a typical condition, maybe not appropriate for dumping
out an exception.
Original comment by eric.woo...@gmail.com
on 17 Feb 2012 at 9:52
The random client id is not a permanent solution. Ideally, it should be server
issued.
Original comment by eric.woo...@gmail.com
on 17 Feb 2012 at 9:58
Original issue reported on code.google.com by
shaman.sir
on 5 Jun 2011 at 9:09