Libwebsocket client example

后端 未结 2 2038
不思量自难忘°
不思量自难忘° 2021-02-01 07:39

I am trying to find a example which will explain me how to implement Client using libwebsocket, But I didn\'t get any convincing code. Is there any link that I can refer to?

2条回答
  •  遥遥无期
    2021-02-01 08:36

    Corrected the code example by Ren-Wei Luo to work with libwebsockets 1.6

    Tested on Ubuntu 14.04

    example-server.c

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define KGRN "\033[0;32;32m"
    #define KCYN "\033[0;36m"
    #define KRED "\033[0;32;31m"
    #define KYEL "\033[1;33m"
    #define KMAG "\033[0;35m"
    #define KBLU "\033[0;32;34m"
    #define KCYN_L "\033[1;36m"
    #define RESET "\033[0m"
    
    static int destroy_flag = 0;
    
    static void INT_HANDLER(int signo) {
        destroy_flag = 1;
    }
    
    /* *
     * websocket_write_back: write the string data to the destination wsi.
     */
    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_ESTABLISHED:
                printf(KYEL"[Main Service] Connection established\n"RESET);
                break;
    
            //* If receive a data from client*/
            case LWS_CALLBACK_RECEIVE:
                printf(KCYN_L"[Main Service] Server recvived:%s\n"RESET,(char *)in);
    
                //* echo back to client*/
                websocket_write_back(wsi ,(char *)in, -1);
    
                break;
        case LWS_CALLBACK_CLOSED:
                printf(KYEL"[Main Service] Client close.\n"RESET);
            break;
    
        default:
                break;
        }
    
        return 0;
    }
    
    struct per_session_data {
        int fd;
    };
    
    int main(void) {
        // server url will usd port 5000
        int port = 5000;
        const char *interface = NULL;
        struct lws_context_creation_info info;
        struct lws_protocols protocol;
        struct lws_context *context;
        // Not using ssl
        const char *cert_path = NULL;
        const char *key_path = NULL;
        // no special options
        int opts = 0;
    
    
        //* 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);
    
        //* setup websocket protocol */
        protocol.name = "my-echo-protocol";
        protocol.callback = ws_service_callback;
        protocol.per_session_data_size=sizeof(struct per_session_data);
        protocol.rx_buffer_size = 0;
    
        //* setup websocket context info*/
        memset(&info, 0, sizeof info);
        info.port = port;
        info.iface = interface;
        info.protocols = &protocol;
        info.extensions = lws_get_internal_extensions();
        info.ssl_cert_filepath = cert_path;
        info.ssl_private_key_filepath = key_path;
        info.gid = -1;
        info.uid = -1;
        info.options = opts;
    
        //* create libwebsocket context. */
        context = lws_create_context(&info);
        if (context == NULL) {
            printf(KRED"[Main] Websocket context create error.\n"RESET);
            return -1;
        }
    
        printf(KGRN"[Main] Websocket context create success.\n"RESET);
    
        //* websocket service */
        while ( !destroy_flag ) {
            lws_service(context, 50);
        }
        usleep(10);
        lws_context_destroy(context);
    
        return 0;
    }
    

    example-client.c

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #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;
    };
    
    struct pthread_routine_tool {
        struct lws_context *context;
        struct lws *wsi;
    };
    
    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;
                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 recvived:%s\n"RESET, (char *)in);
    
                if (writeable_flag)
                    destroy_flag = 1;
    
                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;
    }
    
    static void *pthread_routine(void *tool_in)
    {
        struct pthread_routine_tool *tool = tool_in;
    
        printf(KBRN"[pthread_routine] Good day. This is pthread_routine.\n"RESET);
    
        //* waiting for connection with server done.*/
        while(!connection_flag)
            usleep(1000*20);
    
        //*Send greeting to server*/
        printf(KBRN"[pthread_routine] Server is ready. send a greeting message to server.\n"RESET); 
        websocket_write_back(tool->wsi, "Good day", -1);
    
        printf(KBRN"[pthread_routine] sleep 2 seconds then call onWritable\n"RESET);
        sleep(1);
        printf(KBRN"------------------------------------------------------\n"RESET);
        sleep(1);
        //printf(KBRN"[pthread_routine] sleep 2 seconds then call onWritable\n"RESET);
    
        //*involked wriable*/
        printf(KBRN"[pthread_routine] call on writable.\n"RESET);   
        lws_callback_on_writable(tool->wsi);
    
    }
    
    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, "localhost", 5000, 0,
                "/", "localhost:5000", 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);
    
        struct pthread_routine_tool tool;
        tool.wsi = wsi;
        tool.context = context;
    
        pthread_t pid;
        pthread_create(&pid, NULL, pthread_routine, &tool);
        pthread_detach(pid);
    
        while(!destroy_flag)
        {
            lws_service(context, 50);
        }
    
        lws_context_destroy(context);
    
        return 0;
    }
    

    makefile

    .PHONY:clean
    
    all:example-client example-server
    
    example-client:example-client.c
        gcc example-client.c -o example-client -lpthread -lwebsockets
    
    example-server:example-server.c
        gcc example-server.c -o example-server -lwebsockets
    
    clean:
        -rm example-client example-server
    

提交回复
热议问题