WebSocket

概述

websocket是一个用C实现的轻量级的websocket客户端,支持TLS。

示例代码

创建并连接一个websocket

static rws_socket _socket = NULL;
static int state_flags = 0;

static void on_socket_received_text(rws_socket socket, const char *text, const unsigned int length, bool is_finish)
{
    char *buff = NULL;

    if (!socket || !text || !length) {
        DBG("%s: Invalid parameter(s).", __FUNCTION__);
        return;
    }

    buff = (char *)aos_malloc(length + 1);
    if (!buff) {
        DBG("%s: Not enough memory. len:%d", __FUNCTION__, length + 1);
        return;
    }

    state_flags &= (~WEBSOCKET_DATA_NOT_RECVED);

    memcpy(buff, text, length);
    buff[length] = 0;

    DBG("%s: Socket text: %s", __FUNCTION__, buff);
    aos_free(buff);
    buff = NULL;
}

static void on_socket_received_bin(rws_socket socket, const void * data, const unsigned int length, bool is_finish)
{
    char *buff = NULL;

    if (!socket || !data || !length) {
        DBG("%s: Invalid parameter(s).", __FUNCTION__);
        return;
    }

    buff = (char *)aos_malloc(length + 1);
    if (!buff) {
        DBG("%s: Not enough memory. len:%d", __FUNCTION__, length + 1);
        return;
    }

    state_flags &= ~WEBSOCKET_DATA_NOT_RECVED;

    memcpy(buff, data, length);
    buff[length] = 0;

    DBG("%s: Socket bin: \n%s", __FUNCTION__, buff);
    aos_free(buff);
    buff = NULL;
}

static void on_socket_received_pong(rws_socket socket)
{
    if (!socket) {
        DBG("%s: Invalid parameter(s).", __FUNCTION__);
        return;
    }
    DBG("received pong!!!!!!!!!!!");
}

static void on_socket_connected(rws_socket socket)
{
    const char * test_send_text =
        "{\"version\":\"1.0\",\"supportedConnectionTypes\":[\"websocket\"],\"minimumVersion\":\"1.0\",\"channel\":\"/meta/handshake\"}";

    DBG("%s: Socket connected", __FUNCTION__);

    state_flags |= WEBSOCKET_CONNECTED;
    state_flags &= ~WEBSOCKET_DISCONNECTED;
    rws_socket_send_text(socket, test_send_text);
}

static void on_socket_disconnected(rws_socket socket)
{
    rws_error error = rws_socket_get_error(socket);
    if (error) {
        DBG("%s: Socket disconnect with code, error: %i, %s",
            __FUNCTION__,
            rws_error_get_code(error),
            rws_error_get_description(error));
    }

    state_flags &= ~WEBSOCKET_CONNECTED;
    state_flags |= WEBSOCKET_DISCONNECTED;
    _socket = NULL;
}


int websoc_cli_test_int(const char *scheme, const char *host,
                        const char *path, const int port,
                        const char *cert)
{
    int sleep_count = 0;

    if (!scheme || !host || !path) {
        DBG("%s: Invalid parameter(s).", __FUNCTION__);
        return -1;
    }

    if (_socket) {
        DBG("%s: Socket is not closed.", __FUNCTION__);
        return -2;
    }

    _socket = rws_socket_create(); // create and store socket handle
    CHECK_RET_WITH_RET(_socket, -1);

    state_flags = 0;
    state_flags |= WEBSOCKET_DATA_NOT_RECVED;

    rws_socket_set_scheme(_socket, scheme);
    rws_socket_set_host(_socket, host);
    rws_socket_set_path(_socket, path);
    rws_socket_set_port(_socket, port);

#ifdef WEBSOCKET_SSL_ENABLE
    if (cert) {
        rws_socket_set_server_cert(_socket, cert, strlen(cert) + 1);
    }
#endif

    rws_socket_set_on_disconnected(_socket, &on_socket_disconnected);
    rws_socket_set_on_connected(_socket, &on_socket_connected);
    rws_socket_set_on_received_text(_socket, &on_socket_received_text);
    rws_socket_set_on_received_bin(_socket, &on_socket_received_bin);
    rws_socket_set_on_received_pong(_socket, &on_socket_received_pong);

    rws_socket_connect(_socket);

    /* Connecting */
    while ((!(state_flags & WEBSOCKET_CONNECTED)) &&
           (!(state_flags & WEBSOCKET_DISCONNECTED))) {
        rws_thread_sleep(1000);
        sleep_count++;
        if (30 == sleep_count) {
            break;
        }
    }

    /* Receiving data */
    sleep_count = 0;
    if (state_flags & WEBSOCKET_CONNECTED) {
        while ((state_flags & WEBSOCKET_DATA_NOT_RECVED) && _socket &&
               (rws_true == rws_socket_is_connected(_socket))) {
            rws_thread_sleep(1000);
            sleep_count++;
            if (20 == sleep_count) {
                break;
            }
        }
    }

    if (_socket) {
        rws_socket_disconnect_and_release(_socket);
    }

    _socket = NULL;

    return state_flags & WEBSOCKET_DATA_NOT_RECVED ? -3 : 0;
}

使用说明

创建一个websocket并获得句柄

  // Define variable or field for socket handle
  rws_socket _socket = NULL;
  ............
  // Create socket object
  _socket = rws_socket_create();

设置websocket连接的url

// Combined url: "ws://echo.websocket.org:80/"
rws_socket_set_scheme(_socket, "ws");
rws_socket_set_host(_socket, "echo.websocket.org");
rws_socket_set_port(_socket, 80);
rws_socket_set_path(_socket, "/");

设置websocket的监听回调函数

警告: rws_socket_set_on_disconnected 这个回调是必须设置的

// 主要的回调函数
// socket断开时调用
static void on_socket_disconnected(rws_socket socket) {
  // process error
  rws_error error = rws_socket_get_error(socket);
  if (error) {
    printf("\nSocket disconnect with code, error: %i, %s", rws_error_get_code(error), rws_error_get_description(error)); 
  }
  // forget about this socket object, due to next disconnection sequence
  _socket = NULL;
}
// socket连接,握手成功触发调用
static void on_socket_connected(rws_socket socket) {
  printf("\nSocket connected");
}
// 接收到文本信息时触发调用
static void on_socket_received_text(rws_socket socket, const char * text, const unsigned int length) {
  printf("\nSocket text: %s", text);
}
..................
// 设置socket回调函数
rws_socket_set_on_disconnected(_socket, &on_socket_disconnected); // 必须的
rws_socket_set_on_connected(_socket, &on_socket_connected);
rws_socket_set_on_received_text(_socket, &on_socket_received_text);

连接

rws_socket_connect(_socket);

发送消息

const char * example_text =
  "{\"version\":\"1.0\",\"supportedConnectionTypes\":[\"websocket\"],\"minimumVersion\":\"1.0\",\"channel\":\"/meta/handshake\"}";
rws_socket_send_text(_socket, example_text);

断开连接,删除websocket

rws_socket_disconnect_and_release(_socket);
_socket = NULL;

results matching ""

    No results matching ""