[英]calling libwebsockets server from TooTallNate/Java-Websockets fails
我已經用libwebsockets在C ++中實現了一個websockets服務器。 當我通過任何使用TLS或不使用TLS的網絡瀏覽器撥打電話時,它都可以工作。 當我使用TooTallNate / Java-Websockets庫從android應用程序調用它時,如果服務器不使用數字證書,它將起作用,但是如果服務器使用了數字證書(如果我想使用TLS,則需要這樣做),服務器將被阻止(並且確實不響應新消息),應用在onClose上會收到1006錯誤(int代碼,字符串原因,布爾型遠程)。 無論是否在客戶端上使用SSL,都會發生這種情況。 問題出在libwebsockets.c的第2040行上:
eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);
它在服務器上阻止,直到我殺死了android應用。
這是應用程序上的相關代碼:
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對我來說有點晦澀難懂)
此致Juanjo
更新:libwebsockets.c代碼在這里: https : //github.com/davidgaleano/libwebsockets/blob/master/lib/libwebsockets.c ,看來我有以前的版本。 現在的行是2037。考慮到沒有任何發行版,而且似乎是來自原始warmcat / libwebsockets的舊版本的分支,我想主要的問題是在那個庫中。
解決方案是使用原始的libwebsockets庫(而不是fork),並實現TrustManager包裝器以傳遞給sslContext.init。 該包裝器獨立驗證服務器證書。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.