如何将libwebsockets C客户端连接到wsrelay服务器(node.js)



在我的mac上,我安装并运行wsrelay

$ wsrelay
listening on port 8124...

在Ubuntu 14.04上,我编译并运行了一个简单的libwebsockets客户端,该客户端连接到wsrelay

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <libwebsockets.h>
#define KGRN "33[0;32;32m"
#define KCYN "33[0;36m"
#define KRED "33[0;32;31m"
#define KYEL "33[1;33m"
#define KBLU "33[0;32;34m"
#define KCYN_L "33[1;36m"
#define KBRN "33[0;33m"
#define RESET "33[0m"
static int destroy_flag = 0;
static int connection_flag = 0;
static int writeable_flag = 0;
static void INT_HANDLER(int signo) {
    destroy_flag = 1;
}
struct session_data {
    int fd;
};
static int websocket_write_back(struct lws *wsi_in, char *str, int str_size_in) 
{
    if (str == NULL || wsi_in == NULL)
        return -1;
    int n;
    int len;
    char *out = NULL;
    if (str_size_in < 1) 
        len = strlen(str);
    else
        len = str_size_in;
    out = (char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
    //* setup the buffer*/
    memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, str, len );
    //* write out*/
    n = lws_write(wsi_in, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
    printf(KBLU"[websocket_write_back] %sn"RESET, str);
    //* free the buffer*/
    free(out);
    return n;
}

static int ws_service_callback(
                         struct lws *wsi,
                         enum lws_callback_reasons reason, void *user,
                         void *in, size_t len)
{
    switch (reason) {
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
            printf(KYEL"[Main Service] Connect with server success.n"RESET);
            connection_flag = 1;
            websocket_write_back(wsi, "CLT - Client connected to server!", -1);
            break;
        case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
            printf(KRED"[Main Service] Connect with server error.n"RESET);
            destroy_flag = 1;
            connection_flag = 0;
            break;
        case LWS_CALLBACK_CLOSED:
            printf(KYEL"[Main Service] LWS_CALLBACK_CLOSEDn"RESET);
            destroy_flag = 1;
            connection_flag = 0;
            break;
        case LWS_CALLBACK_CLIENT_RECEIVE:
            printf(KCYN_L"[Main Service] Client received:%sn"RESET, (char *)in);
            break;
        case LWS_CALLBACK_CLIENT_WRITEABLE :
            printf(KYEL"[Main Service] On writeable is called. send byebye messagen"RESET);
            websocket_write_back(wsi, "Byebye! See you later", -1);
            writeable_flag = 1;
            break;
        default:
            break;
    }
    return 0;
}

int main(void)
{
    //* register the signal SIGINT handler */
    struct sigaction act;
    act.sa_handler = INT_HANDLER;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction( SIGINT, &act, 0);
    struct lws_context *context = NULL;
    struct lws_context_creation_info info;
    struct lws *wsi = NULL;
    struct lws_protocols protocol;
    memset(&info, 0, sizeof info);
    info.port = CONTEXT_PORT_NO_LISTEN;
    info.iface = NULL;
    info.protocols = &protocol;
    info.ssl_cert_filepath = NULL;
    info.ssl_private_key_filepath = NULL;
    info.extensions = lws_get_internal_extensions();
    info.gid = -1;
    info.uid = -1;
    info.options = 0;
    protocol.name  = "my-echo-protocol";
    protocol.callback = &ws_service_callback;
    protocol.per_session_data_size = sizeof(struct session_data);
    protocol.rx_buffer_size = 0;
    protocol.id = 0;
    protocol.user = NULL;
    context = lws_create_context(&info);
    printf(KRED"[Main] context created.n"RESET);
    if (context == NULL) {
        printf(KRED"[Main] context is NULL.n"RESET);
        return -1;
    }
    wsi = lws_client_connect(context, "Mac-IP-address", 8124, 0,
            "/", "Mac-IP-address:8124", NULL,
             protocol.name, -1);
    if (wsi == NULL) {
        printf(KRED"[Main] wsi create error.n"RESET);
        return -1;
    }
    printf(KGRN"[Main] wsi create success.n"RESET);
    while(!destroy_flag)
    {
        lws_service(context, 50);
    }
    lws_context_destroy(context);
    return 0;
}

但是当我运行客户端时,使用websocket_write_back发送到服务器的消息从未到达服务器,尽管连接似乎已经正确建立。我猜这是关于协议的问题??关于我可能做错了什么,有什么建议吗?

$ ./example-client 
[1452543414:0970] NOTICE: Initial logging level 7
[1452543414:0971] NOTICE: Libwebsockets version: 1.6.0 0c7e5a9
[1452543414:0971] NOTICE: IPV6 not compiled in
[1452543414:0971] NOTICE: libev support not compiled in
[1452543414:0972] NOTICE:  mem: platform fd map:  8192 bytes
[1452543414:0972] NOTICE:  mem: per-conn:          352 bytes + protocol rx buf
[1452543414:0972] NOTICE:  canonical_hostname = linux-Lenovo-G50-70
[Main] context created.
[Main] wsi create success.
[Main Service] Connect with server success.
[websocket_write_back] CLT - Client connected to server!

不确定在此期间是否成功解决了问题。我的猜测是:您的代码很好,wsrelay有问题。

我已经运行了你的代码(gcc抱怨一些打字员,我会在这个答案的底部添加diff),一切似乎都很好。然而,wsrelay并没有像您所说的那样报告任何内容,这是可疑的,所以我创建了不同的ws服务器。基本上相同的功能(我想,从未真正看到wsrelay工作…)-它记录客户端连接,打印发送的消息,还记录客户端断开连接。

此服务器能够捕获您的消息。因此,我鼓励您删除wsrelay,并使用下面的服务器代码作为基础。这是我在这里找到的一个代码的精简版本。希望这能有所帮助。

WS服务器源

var webSocketsServerPort = 8124;
var webSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {});
server.listen(webSocketsServerPort, function() {
    console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});
var wsServer = new webSocketServer({httpServer: server});
wsServer.on('request', function(request) {
    console.log((new Date()), 'New connection.');
    var connection = request.accept();
    connection.on('message', function(message) {
        console.log(message.utf8Data);
    });
    connection.on('close', function(connection) {
        console.log((new Date()), 'Connection closed.');
    });
});

WS服务器输出

$ node server.js 
Sun Feb 14 2016 13:57:43 GMT+0100 (CET) Server is listening on port 8124
Sun Feb 14 2016 13:57:44 GMT+0100 (CET) 'New connection.'
CLT - Client connected to server!
Byebye! See you later
Byebye! See you later
Sun Feb 14 2016 13:58:31 GMT+0100 (CET) 'Connection closed.'

您的C客户端输出(来自gdb)

$ gdb stack
...
(gdb) run
Starting program: /tmp/stack 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[1455454664:6989] NOTICE: Initial logging level 7
[1455454664:6989] NOTICE: Libwebsockets version: 1.6.0 unknown-build-hash
[1455454664:6989] NOTICE: IPV6 not compiled in
[1455454664:6989] NOTICE: libev support not compiled in
[1455454664:6989] NOTICE:  ctx mem: 21088 bytes
[1455454664:6990] NOTICE:  canonical_hostname = gentee
[1455454664:6990] NOTICE:  per-conn mem: 256 + 2126 headers + protocol rx buf
[Main] context created.
[Main] wsi create success.
[Main Service] Connect with server success.
[websocket_write_back] CLT - Client connected to server!
[Main Service] On writeable is called. send byebye message
[websocket_write_back] Byebye! See you later
[Main Service] On writeable is called. send byebye message
[websocket_write_back] Byebye! See you later
^C

Diff(为了运行您的客户端,我必须进行修改)

$ diff --unchanged-line-format="" --old-line-format="" --new-line-format="%dn: %L" /tmp/stack.*
36:     unsigned char *out = NULL;
43:     out = (unsigned char *)malloc(sizeof(unsigned char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
68:             websocket_write_back(wsi, (char *)"CLT - Client connected to server!", -1);
89:             websocket_write_back(wsi, (char *)"Byebye! See you later", -1);
141:     wsi = lws_client_connect(context, "localhost", 8124, 0,
142:             "/", "localhost:8124", NULL,

相关内容

  • 没有找到相关文章

最新更新