Using Socket.IO on android Always Returns XHR Poll Error
This will also happen if you forgot to set transport in options
IO.Options opts = new IO.Options();
opts.transports = new String[]{WebSocket.NAME}; //or Polling.NAME
After further testing I found the following:
- If you debug your socket when you encounter different events (i.e. EVENT_ERROR), the exception you catch will contain the response code received from the address you tried to reach.
- In my case when attempting to reach my server with HTTP I received a 301 response code because the URL I tried reaching automatically redirected me to the HTTPS address.
- When attempting to reach the HTTPS address I received a 401 response code - meaning the request my socket made had reached the server but was not authorized - The reason for that was that the target server had basic authentication turned on and I didn't supply the required credentials in the socket request headers.
- After supplying the required headers I managed to connect to the socket server properly, but when sending out a request it failed and my socket went back to a re-connection attempt loop - The reason for that was that the JSON I sent to the server from my Android phone was not in the format expected and the server failed to receive that request.
The code I used to add a basic authentication header to my socket request:
// Adding authentication headers when encountering EVENT_TRANSPORT
mSocket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Transport transport = (Transport) args[0];
// Adding headers when EVENT_REQUEST_HEADERS is called
transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.v(TAG, "Caught EVENT_REQUEST_HEADERS after EVENT_TRANSPORT, adding headers");
Map<String, List<String>> mHeaders = (Map<String, List<String>>)args[0];
mHeaders.put("Authorization", Arrays.asList("Basic bXl1c2VyOm15cGFzczEyMw=="));
}
});
}
});
If you encounter and XHR Poll error when you attempt to use Socket.IO, make sure that the connection to your socket server is available and that you are connecting properly. In the end in my case it all revolved around the server requiring basic authentication and me not supplying it when contacting the server.
Also, because I encountered that solution qutie a bit while trying to sovle this issue - When trying to reach your server over HTTPS, you usually don't need a special hostname verifier or special certificate manager. Try and avoid such solutions as they greatly harm the security of your app.
I can verify similar issue with my situation. I am testing websocket connection to a development server. No SSL, just plain http. Here was my situation:
- Tested the apps websocket connection to dev server using android studio simulator - connected successfully made with no error.
- Tested no. (1) above with real device instead of simulator. Failed with the
"xhr poll error"
message. Then, after so much time with no success, I added in
AndroidManifest.xml
the following:<application ... android:usesCleartextTraffic="true" ...>
My project is currently targeting API 28, hence default for "usesCleartextTraffic"
is false. Now everything is working fine.