Jump to Navigation

Tox API - 开始C API

开始C API

现在给出一个简单的C客户端程序的基本结构,后面详细解释每个重要的部分。

#define SLEEP_TIME 50000
#define BOOTSTRAP_ADDRESS "23.226.230.47"
#define BOOTSTRAP_PORT 33445
#define BOOTSTRAP_KEY "A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074"

#define MY_NAME "ImoutoBot"

void hex_string_to_bin(const char *in, uint8_t *out) {
    ...
}

void MyFriendRequestCallback(Tox *tox, uint8_t * public_key, uint8_t * data, uint16_t length, void *userdata) {
   ...
}

void MyFriendMessageCallback(Tox *tox, int friendnumber, uint8_t * message, uint32_t length, void *userdata) {
   ...
}

...

int main(int argc, const char *argv[]) {
    uint8_t *pub_key = malloc(TOX_CLIENT_ID_SIZE);
    hex_string_to_bin(BOOTSTRAP_KEY, pub_key);

    Tox *my_tox = tox_new(TOX_ENABLE_IPV6_DEFAULT);

    /* Register the callbacks */
    tox_callback_friend_request(my_tox, MyFriendRequestCallback, NULL);
    tox_callback_friend_message(my_tox, MyFriendMessageCallback, NULL);
    ...

    /* Define or load some user details for the sake of it */
    tox_set_name(my_tox, MY_NAME, strlen(MY_NAME)); // Sets the username
    tox_set_status_message(my_tox, uint8_t *status, uint16_t length); // user status is pre-defined ints for "online", "offline" etc.
    tox_set_user_status(my_tox, uint8_t userstatus); // status message is a string the user can set

    ...

    tox_bootstrap_from_address(my_tox, BOOTSTRAP_ADDRESS, TOX_ENABLE_IPV6_DEFAULT, BOOTSTRAP_PORT, pub_key); // connect to a bootstrap to get into the network

    ...

    while (1) {
        tox_do(my_tox); // will call the callback functions defined and registered

        ...

        usleep(SLEEP_TIME); // sleep for cpu usage, tox_wait() can be used instead for blocking
    }

    ...

    tox_kill(my_tox);
    return 0;
}

回调函数

Alt Text

当Tox连接有重要事件发生时,tox_do会调用使用以下函数指定的回调函数。

  • api/tox_callback_friend_request
  • api/tox_callback_friend_message
  • api/tox_callback_friend_action
  • api/tox_callback_name_change
  • api/tox_callback_status_message
  • api/tox_callback_user_status
  • api/tox_callback_typing_change
  • api/tox_callback_read_receipt
  • api/tox_callback_connection_status
  • api/tox_callback_group_invite
  • api/tox_callback_group_message
  • api/tox_callback_group_action
  • api/tox_callback_group_namelist_change
  • api/tox_callback_file_send_request
  • api/tox_callback_file_control
  • api/tox_callback_file_data

哦,很多函数啊!不要担心,你仅需要设置你想收到的事件的回调函数。

用户详情

客户端应该在连接到初始化节点前设置用户详情。

所需最基本的用户详情是用户名,这会在连接到他们之后显示出来。

tox_set_name(my_tox, MY_NAME, strlen(MY_NAME));

像用户名一样,你还可以设置用户的状态,表示他们的可用状态。online, offline, away 和 busy。这些是枚举变量TOX_USERSTATUS的一部分,并不是字符串。

tox_set_user_status(my_tox, uint8_t userstatus);

最后,用户还可以有一个字符串类型的状态消息:

tox_set_status_message(my_tox, uint8_t *status, uint16_t length);

接入网络

提示:你应该阅读连接到网络来学习更多的初始化。

一旦你注册了回调函数并设置了用户详情,现在你希望连接到初始化结点并接入到网络。

tox_bootstrap_from_address(my_tox, BOOTSTRAP_ADDRESS, TOX_ENABLE_IPV6_DEFAULT, BOOTSTRAP_PORT, pub_key);

这个函数接受IP或者主机名两种方式的初始化地址。你还可以通过传递一个非0值TOX_ENABLE_IPV6_DEFAULT开启IPv6支持。

让tox_do()执行

tox_do()函数是Tox API 的核心点。它在一个函数中封装了所有网络连接相关功能。你的主循环必须至少每秒调用20次tox_do()函数。反过来,tox_do()函数会调用你注册的函数。

等待事件通知你

每秒调用20次tox_do()函数效率比较低,但如果有重要事件发生呢?这有设计的tox_wait...函数解决它。它像POSIX的select(2)一样工作,因而你可以等待连接上的事件发生,而不是轮询它。

  • api/tox_wait_prepare
  • api/tox_wait_execute
  • api/tox_wait_cleanup

准备

uint16_t rtmp = 0;
tox_wait_prepare(my_tox, NULL, &rtmp);
uint8_t* tox_wait_buffer = malloc(rtmp);

tox_wait_execute()需要一个缓冲区执行工作。使用tox_wait_prepare()函数获取所需的缓冲区大小,并把值存储在rtmp中。然后使用malloc(rtmp)获得正确大小的缓冲区。

开始工作

int error = 0;
error = tox_wait_execute(my_tox, tox_wait_buffer, rtmp, 999);
tox_wait_cleanup(my_tox, tox_wait_buffer, rtmp);
free(tox_wait_buffer);
tox_do(my_tox);

tox_wait_execute()会一直阻塞到你需要调用tox_do()的时候,或者超时(在例子中我们使用了999毫秒)。一般来说,如果是超时返回,你都应该调用tox_do()。

在调用完tox_wait_execute()之后,需要使用m参数调用tox_wait_cleanup(),除了超时。之前申请的缓冲区现在已经不需要了,需要释放掉。

全部整合起来

这还是C示例程序,不过这次使用了tox_wait...函数,而不是休眠循环。

#define BOOTSTRAP_ADDRESS "23.226.230.47"
#define BOOTSTRAP_PORT 33445
#define BOOTSTRAP_KEY "A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074"

#define MY_NAME "ImoutoBot"

void hex_string_to_bin(const char *in, uint8_t *out) {
    ...
}

void hex_string_to_bin(const char *in, uint8_t *out) {
   ...
}

void MyFriendRequestCallback(Tox *tox, uint8_t * public_key, uint8_t * data, uint16_t length, void *userdata) {
  ...
}

void MyFriendMessageCallback(Tox *tox, int friendnumber, uint8_t * message, uint32_t length, void *userdata) {
  ...
}

int main(int argc, const char *argv[]) {
    uint8_t *pub_key = malloc(TOX_CLIENT_ID_SIZE);
    hex_string_to_bin(BOOTSTRAP_KEY, pub_key);

    Tox *my_tox = tox_new(TOX_ENABLE_IPV6_DEFAULT);
    tox_set_name(my_tox, MY_NAME, strlen(MY_NAME));
    ...
    tox_bootstrap_from_address(my_tox, BOOTSTRAP_ADDRESS, TOX_ENABLE_IPV6_DEFAULT, BOOTSTRAP_PORT, pub_key);
    ...
    while (1) {
        uint16_t rtmp = 0;
        tox_wait_prepare(my_tox, NULL, &rtmp);
        uint8_t* tox_wait_buffer = malloc(rtmp);
        int error = 0;
        error = tox_wait_execute(my_tox, tox_wait_buffer, rtmp, 999);
        tox_wait_cleanup(my_tox, tox_wait_buffer, rtmp);
        free(tox_wait_buffer);

        tox_do(my_tox);
        ...
    }
    ...
    tox_kill(my_tox);
    return 0;
}

提示:你并不需要每次调用tox_wait_execute()函数都申请新的缓冲。

Category:

添加新评论

Plain text

  • 不允许HTML标记。
  • 自动将网址与电子邮件地址转变为链接。
  • 自动断行和分段。
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.


Main menu 2

Story | by Dr. Radut