在Android上连接到Pushbullet的Secure Websocket

时间:2015-05-22 02:31:40

标签: android ssl websocket pushbullet

Pushbullet的强大服务有一个websocket流,您可以订阅,然后监听推送到您的设备,这正是我想要的。我希望我的应用程序能够连接到消息流并根据他们所说的内容做些事情。

我已尝试使用https://github.com/andrepew/Java-WebSocket/tree/1.3.0-Android-SSL-Fix(从https://github.com/TooTallNate/Java-WebSocket分叉),但我没有运气。在一段时间超时后,连接响应返回

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

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)

我的代码是(没有我的访问令牌......)甚至尝试"信任所有主机"暗示黑客,

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();
    }
}

3 个答案:

答案 0 :(得分:1)

从该错误中我只能猜测它可能存在SSL的一些问题。您可以尝试使用另一种(未记录的)流式端点来帮助调试此问题。如果您向https://stream.pushbullet.com/streaming/ACCESS_TOKEN_HERE发出请求,它将返回一个分块的HTTP响应,该响应一直持续到断开连接为止。如果你能弄清楚如何阅读这个流媒体响应(许多http客户端可以做到这一点),那么至少那部分工作,它只是你的websocket库。

您可以使用curl --no-buffer从命令行使用流媒体内容。您应该在连接后立即看到一条nop消息。

答案 1 :(得分:1)

您可能更容易在Android上使用流式传输(长期存在的HTTP连接)而不是WebSocket。以下是我在Android上使用的一些示例代码:

final URL url = new URL("https://stream.pushbullet.com/streaming/" + <USER_API_KEY>);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(38000);
connection.setConnectTimeout(8000);
connection.setRequestMethod("GET");
connection.setDoInput(true);

L.i("Connecting to stream server");

connection.connect();

final int responseCode = connection.getResponseCode();
if (responseCode != 200) {
    throw new QuietException("Unable to connect to stream, server returned " + responseCode);
}

final InputStream inputStream = connection.getInputStream();

try {
    final BufferedReader stream = new BufferedReader(new InputStreamReader(inputStream));

    final String line = stream.readLine();
    final JSONObject message = new JSONObject(line);
    // And now you can do something based on this message
} finally {
    inputStream.close();
}

当您的应用程序处于打开状态时,此功能非常有用。如果你想一直得到消息,那就更难了。您需要通过GCM接收消息,这意味着要为我们创建一个设备,以便为您的应用发送消息。如果您需要这些,我建议发送电子邮件至api@pushbullet.com以获取更多帮助。

答案 2 :(得分:0)

据我从错误中可以看出,你使用的Draft_10相当陈旧。

您应该使用当前草稿[Draft_17]:

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

并添加到导入:

import org.java_websocket.drafts.Draft_10;

如果您有兴趣,可以在此处找到有关草稿的更多信息:

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