【问题标题】:Socket.io client in android connection with HTTPS protocol failed?使用 HTTPS 协议的 android 连接中的 Socket.io 客户端失败?
【发布时间】:2016-10-16 01:18:41
【问题描述】:

服务器上的io和android上的客户端。

只要我启用 HTTP(S) SSL,它就会在 android 上导致连接错误(但是如果禁用它可以正常工作)

我尝试在 Android 上实现 HTTPS 连接,参考 Github 上的示例如下:

opts = new IO.Options();
opts.sslContext = mySSLContext;
opts.hostnameVerifier = myHostnameVerifier;
socket = IO.socket("https://mychat.url", opts);

还有这个

SSLContext mySSLContext = SSLContext.getInstance("TLS");
mySSLContext.init(null, null, null);

还有这个

myHostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
});

在套接字传输过程中仍然收到错误消息

io.socket.engineio.client.EngineIOException: xhr poll error

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

使用 HTTPS 协议实现 socket io 连接需要什么?

【问题讨论】:

标签: android ssl https socket.io tls1.2


【解决方案1】:

感谢@Apurva,我自己解决了。

似乎需要 TrustManager 来初始化 sslContext

所以我加了

mySSLContext.init(null, trustAllCerts, null);

带参数trustAllCerts参考

private final 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 {
    }
} };

终于成功连接到聊天服务器了。

【讨论】:

  • 绝对不可思议!
【解决方案2】:

感谢@Dayo Chou,我通过 https 获得了 socket.io 连接。我正在阅读https://github.com/socketio/socket.io-client-java,但它并没有告诉你你需要的一切。这篇文章仍然缺少这些内容,所以我决定将我的代码发布给任何可能觉得它有用的人。更改 ADDRESS 和 PORT 以满足您的需求。

HostnameVerifier myHostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};
TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

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

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}};

SSLContext mySSLContext = null;
try {
    mySSLContext = SSLContext.getInstance("TLS");
    try {
        mySSLContext.init(null, trustAllCerts, null);
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}
OkHttpClient okHttpClient = new OkHttpClient.Builder().hostnameVerifier(myHostnameVerifier).sslSocketFactory(mySSLContext.getSocketFactory()).build();

// default settings for all sockets
IO.setDefaultOkHttpWebSocketFactory(okHttpClient);
IO.setDefaultOkHttpCallFactory(okHttpClient);

// set as an option
IO.Options opts = new IO.Options();
opts.callFactory = okHttpClient;
opts.webSocketFactory = okHttpClient;

socket = IO.socket("https://" + ADDRESS + ":PORT", opts);
socket.connect();

【讨论】:

  • 我尝试了您的解决方案,但唉!连接似乎卡在“正在连接”上。我从来没有收到来自服务器的Socket.EVENT_CONNECT,只有Socket.EVENT_CONNECTING...
  • 在 Android API 中运行时对我不起作用
  • @Hayuki 尝试添加这一行:opts.transports = new String[]{ WebSocket.NAME };
【解决方案3】:

Kotlin 版本:

    val myHostnameVerifier = HostnameVerifier { _, _ ->
        return@HostnameVerifier true
    }

    val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager
    {
        override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}

        override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}

        override fun getAcceptedIssuers(): Array<X509Certificate> {
            return arrayOf()
        }
    })

    val sslContext = SSLContext.getInstance("TLS")
    sslContext.init(null, trustAllCerts, null)

    val okHttpClient = OkHttpClient.Builder()
                                   .hostnameVerifier(myHostnameVerifier)
                                   .sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
                                   .build()

    val options = IO.Options()
    options.transports = arrayOf(Polling.NAME)
    options.callFactory = okHttpClient
    options.webSocketFactory = okHttpClient

    val socket = IO.socket("https://...", options)
    socket.connect()

【讨论】:

    猜你喜欢
    • 2016-03-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    相关资源
    最近更新 更多