0

The awesome service that is Pushbullet have a websocket stream that you can subscribe to and then listen for pushes to your device, which is exactly what I want. I want my App to be able to connect to the messages stream and do stuff based on what they say.

I've tried using https://github.com/andrepew/Java-WebSocket/tree/1.3.0-Android-SSL-Fix (forked from https://github.com/TooTallNate/Java-WebSocket), but am getting no luck. After a bit of a timeout, the connection response comes back with

onClose -1, draft org.java_websocket.drafts.Draft_10@a38fd36 refuses handshake, false

and

05-22 03:24:30.709  15423-15904 java.lang.NullPointerException: ssl == null
05-22 03:24:30.710  15423-15904 com.android.org.conscrypt.NativeCrypto.SSL_read_BIO(Native Method)
05-22 03:24:30.710  15423-15904 com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:477)
05-22 03:24:30.710  15423-15904 javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1006)

my code to get that is (without my access token...) even trying the "trust all hosts" suggested hack,

private void createConnection()
{
    URI uri = URI.create("wss://stream.pushbullet.com/websocket/" + pushAT);

    final WebSocketClient mWebSocketClient = new WebSocketClient(uri) {
        @Override
        public void onOpen(ServerHandshake serverHandshake) {
            Log.d(TAG, "onOpen " + serverHandshake);
        }

        @Override
        public void onMessage(String s) {
            Log.d(TAG, "onMessage " + s);
        }

        @Override
        public void onClose(int i, String s, boolean b) {
            Log.d(TAG, "onClose " + i + ", " + s + ", " + b);
        }

        @Override
        public void onError(Exception e) {
            Log.d(TAG, "onError " + e);
            e.printStackTrace();
        }
    };

    Log.d(TAG, "Connecting to " + uri);
    trustAllHosts(mWebSocketClient);

    mWebSocketClient.connect();
    Log.d(TAG, "Connecting to " + uri);
}

public void trustAllHosts(WebSocketClient wsc) {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }

        public void checkClientTrusted(X509Certificate[] chain,
                                       String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain,
                                       String authType) throws CertificateException {
        }
    }};


    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        wsc.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sc));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
seaders
  • 3,878
  • 3
  • 40
  • 64

2 Answers2

1

From that error I can only guess that it might have some issue with SSL. There is an alternative (not documented) streaming endpoint you could try that would maybe help debug this issue. If you do a request to https://stream.pushbullet.com/streaming/ACCESS_TOKEN_HERE it returns a chunked HTTP response that keeps going until you disconnect. If you can figure out how to read this streaming response (many http clients can do this) then at least that part works and it's just your websocket library.

You can use the streaming thing from the command line with curl --no-buffer. You should see a nop message immediately upon connection.

Chris Pushbullet
  • 1,039
  • 9
  • 10
  • Hmmm, now that I'm thinking about it, having a consistent stream open may not be the best approach in general. How does the app do it, I'm assuming it's the more standard just push notification in general approach, rather than WSS, yeah? Any way I can piggy back just on those? I mean, how does Tasker grab a hold? – seaders May 22 '15 at 03:01
  • The android app uses standard GCM push notifications. I'm not sure how Tasker grabs those, but I'll check with the android guy. I may implement a thing for other apps to use GCM push notifications, but haven't done that yet. – Chris Pushbullet May 22 '15 at 05:53
0

As far as I can tell from the error, you are using the Draft_10 which is rather old.

You should use the current draft [Draft_17] like this :

final WebSocketClient mWebSocketClient = new WebSocketClient(uri, new Draft_17()) {

And add to imports :

import org.java_websocket.drafts.Draft_10;

If you are interested, you may find more about drafts here:

https://github.com/TooTallNate/Java-WebSocket/wiki/Drafts

komarios
  • 147
  • 4