6

I'm trying to connect to the Stack Exchange chat Websocket. The websocket is used to receive new events in the chat, such as new messages.

Here's the code used to create the Websocket:

String wsUrl = getWsUrl();
Request wsRequest = new Request.Builder()
        .url(wsUrl)
        .build();
WebSocketCall wsCall = WebSocketCall.create(httpClient, wsRequest);
wsCall.enqueue(new ChatWebSocketListener());

The websocket URL is in this form:

wss://chat.sockets.stackexchange.com/events/16/4b3a8a1f68704b8db35ce9f0915c7c45

The WebSocketListener receives a onFailure response only, with this exception:

E/IOException﹕ unexpected end of stream on Connection{chat.sockets.stackexchange.com:443, proxy=DIRECT@ hostAddress=192.111.0.32 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1} (recycle count=0)
    java.io.IOException: unexpected end of stream on Connection{chat.sockets.stackexchange.com:443, proxy=DIRECT@ hostAddress=192.111.0.32 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1} (recycle count=0)
            at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:211)
            at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
            at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
            at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:757)
            at com.squareup.okhttp.Call.getResponse(Call.java:274)
            at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
            at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
            at com.squareup.okhttp.Call.access$100(Call.java:36)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:164)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:831)
     Caused by: java.io.EOFException: \n not found: size=0 content=...
            at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
            at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
            at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
            at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
            at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:757)
            at com.squareup.okhttp.Call.getResponse(Call.java:274)
            at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
            at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
            at com.squareup.okhttp.Call.access$100(Call.java:36)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:164)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:831)

I'm not sure what I'm doing wrong here, or how to interperet this exception. What's wrong with this websocket, and how can I fix it?

Anubian Noob
  • 13,426
  • 6
  • 53
  • 75
  • Are you sure that is the right URL? Try connecting to ws://echo.websocket.org and see if it works. Also note that the stackexchange one might be using an unsupported version of the WebSocket implementations. – Gergely Kőrössy Aug 22 '15 at 23:14
  • @GergelyKőrössy `ws://echo.websocket.org` returns a 400: Bad Request when I try to connect, instead of the 101 we want, but `wss://echo.websocket.org` works fine... – Anubian Noob Aug 22 '15 at 23:30
  • Yeah, the unsecure one doesn't work on the website either. Is it possible that you are being redirected but OkHTTP doesn't implement a redirect mechanism? Or the version of the WebSocket used by the stack exchange is different from the implemented ones in OkHTTP... – Gergely Kőrössy Aug 22 '15 at 23:33
  • @GergelyKőrössy Hmm according to CharlesProxy: `Remote server closed the connection before sending response header`... So it's probably my configuration somewhere, or possibly a compatability issue of some kind... – Anubian Noob Aug 23 '15 at 00:01
  • I think it's gonna be on the stack exchange part, so you cannot do anything. Is it an official URL or you just found it somewhere? It's possible that they don't allow other origin connections. – Gergely Kőrössy Aug 23 '15 at 00:09
  • @GergelyKőrössy Oh that seems rather plausible... Except there are other chat bots that do it. I'd think that the server would at least give me a 404 or 500 or 403 or something, but it just closes the connection... – Anubian Noob Aug 23 '15 at 00:19

2 Answers2

4

The chat websocket server disregards the request unless it has both:

  • A url param l, corresponding to a value sent back when the list of events is loaded.
  • A header Origin set to "http://stackexchange.com".

You just have to add those to your request:

Request wsRequest = new Request.Builder()
        .url(wsUrl+"?l=" + valueFromLoadingEvents)
        .addHeader("Origin", "http://stackexchange.com")
        .build();
Anubian Noob
  • 13,426
  • 6
  • 53
  • 75
  • Could you explain what valueFromLoadingEvents contains? Maybe give an example for this value? – Christian D Jun 14 '17 at 15:04
  • @ChristianD I haven't touched this in a long time, and it might have changed, but if I remember correctly it's a random ID type value on the page that you have to supply to open the connection. – Anubian Noob Jun 23 '17 at 18:13
1

Most probably there are 2 things, happening at the same time.
First, the url contains a port which is not commonly used AND secondly, you are using a VPN or proxy that does not support that port.
Personally, I had the same problem.
My server port was 45860 and I was using pSiphon anti-filter VPN.
In that condition my Postman reported "connection hang-up" only when server's relpy was an error with status codes bigger than 0. (it was fine when some text was returning from server with no error code)
Then I changed my web service port to 8080 on my server and, WOW, it worked! although psiphon vpn was connected.
Therefore, my suggestion is that if you can change the server port, so try it, or check if there is a proxy problem.