java - 从 TooTallNate/Java-Websockets 调用 libwebsockets 服务器失败

标签 java android c++ openssl libwebsockets

我已经用 C++ 和 libwebsockets 实现了一个 websockets 服务器。当我使用或不使用 TLS 从任何 Web 浏览器进行调用时,它都有效。当我使用 TooTallNate/Java-Websockets 库从 Android 应用程序调用它时,如果服务器不使用数字证书,它会工作,但如果它使用(如果我想使用 TLS,则需要)服务器被阻止(并且确实不响应新消息)并且应用程序在 onClose(int code,String reason,boolean remote)上收到 1006 错误。无论我是否在客户端上使用 SSL,它都会发生。 问题出在 libwebsockets.c 的第 2040 行:

eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);

它在服务器上阻塞,直到我终止 android 应用程序。

这是App上的相关代码:

class WebSocketChatClient extends WebSocketClient { 


    public WebSocketChatClient( URI serverUri ) { 
        super( serverUri ); 
    } 

    public WebSocketChatClient( URI serverUri , Draft protocolDraft , Map<String,String> httpHeaders  )
    {
        super(serverUri,protocolDraft,httpHeaders);
    }

    @Override 
    public void onOpen( ServerHandshake handshakedata ) { 
        System.out.println( "Connected" ); 
        send("prueba");

    } 


    @Override 
    public void onMessage( String message ) { 
        System.out.println( "got: " + message ); 


    } 


    @Override 
    public void onClose( int code, String reason, boolean remote ) { 
        System.out.println( "Disconnected" ); 
        //System.exit( 0 ); 


    } 


    @Override 
    public void onError( Exception ex ) { 
        ex.printStackTrace(); 


    } 


 } 




@Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context = getApplicationContext();

        URI uri;
        try
        {
            uri=new URI("wss://192.168.1.128:8080");

            Map<String,String> headers=new HashMap<String,String>();

            headers.put("Sec-WebSocket-Protocol", "dumb-increment-protocol");
            headers.put("User-Agent", "My Android App");
            wsClient = new WebSocketChatClient(uri,new Draft_17(),headers);
            SSLContext sslContext = null;
            try {
                sslContext = SSLContext.getInstance( "TLS" );
                sslContext.init( null, null, null ); // will use java's default key and trust store which is sufficient unless you deal with self-signed certificates
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }



            wsClient.setWebSocketFactory( new DefaultSSLWebSocketClientFactory( sslContext ) );
            wsClient.connect();

        }
        catch(URISyntaxException e)
        {
            e.printStackTrace();
        }
}

这是服务器上的相关代码:

            int port = 8080;
            const char *intrface = NULL;
            struct libwebsocket_context *context;
            // we're not using ssl
            const char *cert_path = "c:\\mydir\\1921681128.crt";
            const char *key_path = "c:\\mydir\\1921681128.key";
            // no special options
            int opts = 0;

            // create libwebsocket context representing this server
            context = libwebsocket_create_context(port, intrface, protocols,
                                          libwebsocket_internal_extensions,
                                          cert_path, key_path, NULL,-1, -1, opts);

            if (context == NULL) {
                fprintf(stderr, "libwebsocket init failed\n");
                return -1;
            }

            printf("starting server...\n");

            // infinite loop, to end this server send SIGTERM. (CTRL+C)
            int k=0;
            while (1) {
                int res=libwebsocket_service(context, 50);
                // libwebsocket_service will process all waiting events with their
                // callback functions and then wait 50 ms.
                // (this is a single threaded webserver and this will keep our server
                // from generating load while there are not requests to process)
                     }

我想知道我这边是否有任何错误,或者它是否是 libwebsockets、openssl 或 java websockets 客户端库上的错误。如果我调用此服务器,客户端工作:ws://echo.websocket.org 使用或不使用 TLS。即使 java 客户端存在错误,我也想知道 ssl_read 不返回并被阻止的正确行为,即使客户端已经检测到问题并返回错误。 (openssl 代码上的 ssl_read 对我来说有点模糊,无法理解)

问候, 胡安乔

更新:libwebsockets.c 代码在这里:https://github.com/davidgaleano/libwebsockets/blob/master/lib/libwebsockets.c看来我有以前的版本。现在该行是 2037。鉴于没有任何版本,而且它似乎是原始 warmcat/libwebsockets 的旧版本的分支,我想主要问题出在那个库中。

最佳答案

解决方案是使用原始的 libwebsockets 库(不是分支)并实现一个 TrustManager 包装器以传递给 sslContext.init。此包装器独立验证服务器证书。

关于java - 从 TooTallNate/Java-Websockets 调用 libwebsockets 服务器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28170631/

相关文章:

java - 使用 Java 反射从类路径外加载类

java - Apache POI 从 XWPFRun 获取换行符

java - 使用 HttpsURLConnection 忽略 ssl 证书的方法

java - Easy-Rules 规则引擎,不能同时触发多个事实

java - 如何在android中自定义共享菜单?

android - 如何在 android 中以编程方式将音频 .mp3 转换为 .m4a

c++ - 从 Turbo C++(旧)切换到较新的类似编译器

c++ - 如何将图像文件夹添加到 CMake 项目以便在 c++ 可执行文件中使用这些图像?

c++ - 如何调试快速通用网关接口(interface) (FCGI) 程序?

java - 如何在动态定义的 Runnable 内部使用它