0

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

3 に答える 3

1

Android では、WebSocket の代わりにストリーミング (長寿命の HTTP 接続) を使用する方が簡単な場合があります。このために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 に電子メールを送信してサポートを求めることをお勧めします。

于 2015-05-22T19:26:20.790 に答える
1

そのエラーから、SSL に何らかの問題がある可能性があるとしか推測できません。この問題のデバッグに役立つかもしれない代替の (文書化されていない) ストリーミング エンドポイントを試すことができます。https://stream.pushbullet.com/streaming/ACCESS_TOKEN_HEREへのリクエストを行うと、切断するまで続くチャンクされた HTTP レスポンスが返されます。このストリーミング応答を読み取る方法を理解できれば (多くの HTTP クライアントでこれを実行できます)、少なくともその部分は機能し、それは単なる websocket ライブラリです。

を使用して、コマンドラインからストリーミングを使用できますcurl --no-buffer。接続するとすぐに nop メッセージが表示されます。

于 2015-05-22T02:55:14.033 に答える