Theldus / wsServer

wsServer - a tiny WebSocket server library written in C
https://theldus.github.io/wsServer
GNU General Public License v3.0
422 stars 80 forks source link

add an #include #1

Closed dj0abr closed 5 years ago

dj0abr commented 5 years ago

thank you for this very (!) nice WebSocket program. It is far the best I found in the web after days of searching, because its simple and does what I need. To make it more compatible to some compilers:

include

should be added to ws.c

Is it easy to modify the receive / send functions for binary data ?

Theldus commented 5 years ago

Thank you @dj0abr for the tip, I'm glad that you like the project, means a lot to me. I've already pushed a commit including the header.

Regarding your question, there's 2 years that I have made this library, so I have to revisit the concepts before to give you a proper answer, but I think that it's not hard at all. In the last case, you can (with some overhead) send/receive binary data as base64 strings... =).

dj0abr commented 5 years ago

Thank you for the answer Theldus, I am currently writing a program for an SDR radio and want to send the decoded spectrum data to a web page. First tests with text data and your library look very promising. If I find out how to transfer binary data I will let you know.

dj0abr commented 5 years ago

ok, its done, was quite easy.

I do not use the receive function, but I think it will need to read the length from the frame.

ws.h:

/* Frame types. */
#define WS_FR_OP_TXT  1
#define WS_FR_OP_BINARY 2
#define WS_FR_OP_CLSE 8

ws.c:

/**
 * Creates and send an WebSocket frame
 * with some binary message.
 * @param fd  Target to be send.
 * @param msg Message to be send.
 */
int ws_sendframe_binary(int fd, unsigned char *msg, uint64_t length)
{
    unsigned char *response;  /* Response data.  */
    unsigned char frame[10];  /* Frame.          */
    uint8_t idx_first_rData;  /* Index data.     */
    int idx_response;      /* Index response. */
    int output;               /* Bytes sent.     */

    /* Binary data. */
    frame[0] = (WS_FIN | WS_FR_OP_BINARY);

    /* Split the size between octects. */
    if (length <= 125)
    {
        frame[1] = length & 0x7F;
        idx_first_rData = 2;
    }

    /* Size between 126 and 65535 bytes. */
    else if (length >= 126 && length <= 65535)
    {
        frame[1] = 126;
        frame[2] = (length >> 8) & 255;
        frame[3] = length & 255;
        idx_first_rData = 4;
    }

    /* More than 65535 bytes. */
    else
    {
        frame[1] = 127;
        frame[2] = (unsigned char) ((length >> 56) & 255);
        frame[3] = (unsigned char) ((length >> 48) & 255);
        frame[4] = (unsigned char) ((length >> 40) & 255);
        frame[5] = (unsigned char) ((length >> 32) & 255);
        frame[6] = (unsigned char) ((length >> 24) & 255);
        frame[7] = (unsigned char) ((length >> 16) & 255);
        frame[8] = (unsigned char) ((length >> 8) & 255);
        frame[9] = (unsigned char) (length & 255);
        idx_first_rData = 10;
    }

    /* Add frame bytes. */
    idx_response = 0;
    response = malloc( sizeof(unsigned char) * (idx_first_rData + length + 1) );
    for (int i = 0; i < idx_first_rData; i++)
    {
        response[i] = frame[i];
        idx_response++;
    }

    /* Add data bytes. */
    for (int i = 0; i < length; i++)
    {
        response[idx_response] = msg[i];
        idx_response++;
    }

    output = write(fd, response, idx_response);
    free(response);
    return (output);
}

example:

/* Do connection. */
ws = new WebSocket("ws://" + addr + ":8080");
ws.binaryType = "arraybuffer";
Theldus commented 5 years ago

Nice, very nice, I also invite you to do a PR with this feature, if you want.. it would be a great addition have the option to send binary data, ;-).