0

On my mac, I installed and run wsrelay

$ wsrelay
listening on port 8124...

On my Ubuntu 14.04, I compiled and run a simple libwebsockets client connecting to the wsrelay

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <libwebsockets.h>

#define KGRN "\033[0;32;32m"
#define KCYN "\033[0;36m"
#define KRED "\033[0;32;31m"
#define KYEL "\033[1;33m"
#define KBLU "\033[0;32;34m"
#define KCYN_L "\033[1;36m"
#define KBRN "\033[0;33m"
#define RESET "\033[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] %s\n"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_CLOSED\n"RESET);
            destroy_flag = 1;
            connection_flag = 0;
            break;

        case LWS_CALLBACK_CLIENT_RECEIVE:
            printf(KCYN_L"[Main Service] Client received:%s\n"RESET, (char *)in);

            break;
        case LWS_CALLBACK_CLIENT_WRITEABLE :
            printf(KYEL"[Main Service] On writeable is called. send byebye message\n"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;
}

but when I run the client, the message sent to the server using websocket_write_back never reaches the server although the connection seems to have established properly. I am guessing this is something about the protocol?? Any pointers about what I may be doing wrong?

$ ./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!
zabumba
  • 12,172
  • 16
  • 72
  • 129

1 Answers1

1

Not sure if you managed to solve it in the meantime. Here's my guess: your code is fine, something is wrong with wsrelay.

I've ran your code (gcc complained about some typings, I'll append diff to the bottom of this answer) and everything seemed to work fine. However wsrelay didn't report anything as you said, which was suspicious, so I created different ws server. Basically the same functionality (I suppose, never actually seen wsrelay work...) - it logs client connection, prints message sent and also logs client disconnection.

This server is able to catch your messages. So I encourage you to remove wsrelay and use below server code as your base. It is a stripped version of a code I've found here. Hope this helps.

WS Server source

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 Server output

$ 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.'

Your C client output (from 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 (modifications I had to do in order to run your client)

$ 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,
kecer
  • 3,031
  • 2
  • 21
  • 24