Android的套接字.Websocket传输在SSL中不起作用



我正在使用gottox套接字。io java客户端用于Android聊天应用程序。
我可以在HTTP模式下连接到web-socket和Xhr传输。但是当我切换到HTTPS只有Xhr模式是工作的。我使用了如下所示的默认SSL上下文

SocketIO.setDefaultSSLSocketFactory(SSLContext.getInstance("Default"));

在Xhr模式下可以正常工作。但是在websocket传输中,没有响应或错误。

更新

可能是新版本的IO.setDefaultSSLContextIO. setDefaultHostnameVerifier方法不可用。相反,现在我们可以创建自己的OkHttpClient,并设置主机名验证器和ssl套接字工厂等。io-client-java使用。下面是来自那里的片段:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                      .hostnameVerifier(myHostnameVerifier)
                      .sslSocketFactory(mySSLContext.getSocketFactory(), myX509TrustManager)
                      .build(); // default settings for all sockets 
IO.setDefaultOkHttpWebSocketFactory(okHttpClient); 
IO.setDefaultOkHttpCallFactory(okHttpClient);

初始答:

我有同样的问题与io.socket:socket.io-client:0.7.0版本的套接字。Android上的io库。它过去可以很好地为http协议工作,但是对于https协议,它在给xhr poll errors建立连接时遇到麻烦。

下面的解决方案不需要修改库本身:

// Socket connection
private Socket mSocket;
// Configure options
IO.Options options = new IO.Options();
// ... add more options
// End point https 
String yourEndpoint = "https://whatever.yoururl.com"
String yourHostName = "yoururl.com"
// If https, explicitly tell set the sslContext.
if (yourEndpoint.startsWith("https://")) {        
    try {
        // Default settings for all sockets
        // Set default ssl context
        IO.setDefaultSSLContext(SSLContext.getDefault());
        // Set default hostname
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
                return hv.verify(yourHostName, session);
            }
        };
        IO.setDefaultHostnameVerifier(hostnameVerifier);
        // set as an option
        options.sslContext = SSLContext.getDefault();
        options.hostnameVerifier = hostnameVerifier;
        options.secure = true;
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}
// Instantiate the socket
mSocket = IO.socket(mEndpoint, options);

它工作,但你必须做一些修改io。套接字图书馆。不要使用socket .jar,而是将io.jar文件导入到src文件夹中。你可以在socket里面找到。io-java-client包)。在这里,你必须编辑WebsocketTransport类。

答案在这里

https://github.com/Gottox/socket.io-java-client/issues/60

 public WebsocketTransport(URI uri, IOConnection connection) {
    super(uri);
    this.connection = connection;
    SSLContext context = null;
    try {
        context = SSLContext.getInstance("TLS", "HarmonyJSSE");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } 
    try {
        context.init(null, null, null);
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
    if("wss".equals(uri.getScheme()) && context != null) {
        this.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(context));
    }
}

记住像这样调用setDefaultSSLSocketFactory:

socket = new SocketIO();
socket.setDefaultSSLSocketFactory(SSLContext.getDefault());
socket.connect("https://www.myHttpsServer.com:443/");

希望对大家有所帮助;)

Websocket with SSL working in AndroidAsync。

最新更新