The reasons are
Android browser websocket support start from 4.4
Android browser 4.1 seems have some issue to support the CROS request
refer to How do I send a cross-domain POST request via JavaScript?.
Must remember few things,
a. Set the Atmosphere javascript long-poll option allowCredentials to true, if using session
b. disable the atmosphere buildin CROS headers through "dropAccessControlAllowOriginHeader" if using the jetty "CrossOriginFilter".
Android (4.1+) webview can use the setAllowUniversalAccessFromFileURLs(true) to tackle the CROS issue
Atmosphere's AtmosphereServlet(2.2.4) doOptions() need be overwritten as the following. In the web.xml, use this new child class instead of the original AtmosphereServlet class to handle the request
public void doOptions(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
{
res.setHeader("Allow", "GET,HEAD,POST");
}
Once the above is done, the android Atmosphere connection will be up for 4.1~4.3.
If the host is the Jetty (9.2+), there is another issue, that the "isAsyncSupported()" check in "AsynchronousProcessor" is always false. And this will cause the following error message
if (isServlet30 && (!req.isAsyncSupported() && !Utils.closeMessage(req)))
In Jetty (9.2+) ServletHandler class, the following code's comments tell you why the req.isAsyncSupported() become false!!! In my case, it is because of google guice filter. it is not async enabled.
//if the request already does not support async, then the setting for the filter
//is irrelevant. However if the request supports async but this filter does not
//temporarily turn it off for the execution of the filter
boolean requestAsyncSupported = baseRequest.isAsyncSupported();
try
{
if (!_filterHolder.isAsyncSupported() && requestAsyncSupported)
baseRequest.setAsyncSupported(false);
filter.doFilter(request, response, _next);
}
finally
{
baseRequest.setAsyncSupported(requestAsyncSupported);
}
return;
To address this, just simply add the "async-supported" into the web.xml for each configured filter.
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
<async-supported>true</async-supported>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<async-supported>true</async-supported>