Android Socket.io Websocket 传输在 SSL 中不起作用

Posted

技术标签:

【中文标题】Android Socket.io Websocket 传输在 SSL 中不起作用【英文标题】:Android Socket.io Websocket Transport does not works in SSL 【发布时间】:2013-04-17 12:25:48 【问题描述】:

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

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

这在 Xhr 模式下运行良好。但是在 websocket 传输中没有响应或错误。

【问题讨论】:

你能分享你的代码,你如何将传输更改为仅 websocket 【参考方案1】:

更新

可能是新版本 IO.setDefaultSSLContextIO. setDefaultHostnameVerifier 方法不可用。相反,现在我们可以创建自己的OkHttpClient 并在其上设置主机名验证器和 ssl 套接字工厂等,如socket.io-client-java usage 中所述。这是那里的代码片段:

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

IO.setDefaultOkHttpWebSocketFactory(okHttpClient); 
IO.setDefaultOkHttpCallFactory(okHttpClient);

初步答案:

我在 Android 上长期使用 io.socket:socket.io-client:0.7.0 版本的 socket.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.setDefaultSSLContextIO. setDefaultHostnameVerifier 在 1.0 版中不再可用 @ffleandro 你用什么代替? @Dap 您现在可能可以创建自己的OkHttpClient 并在其上设置主机名验证器和 ssl 套接字工厂等:OkHttpClient okHttpClient = new OkHttpClient.Builder() .hostnameVerifier(myHostnameVerifier) .sslSocketFactory(mySSLContext.getSocketFactory(), myX509TrustManager) .build(); // default settings for all sockets IO.setDefaultOkHttpWebSocketFactory(okHttpClient); IO.setDefaultOkHttpCallFactory(okHttpClient); @Dap,是的,正如 Shobhit 所描述的那样。【参考方案2】:

它可以工作,但您必须对 io.socket 库进行一些修改。 不要使用 socketio.jar,而是将 io.socket 库导入 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/");

希望它对某人有所帮助;)

【讨论】:

【参考方案3】:

带有 SSL 的 Websocket 在 AndroidAsync 中工作。暂时使用它。

【讨论】:

以上是关于Android Socket.io Websocket 传输在 SSL 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

基于heroku socket.io服务器的heroku空闲连接超时

Android websock 应用

在 android 上解析 socket.io 数据。 (Gottox Socket.IO)

Native Socket.IO and Android

从android与socket.io通信

Android socket.io 编码