Skip to content

Tutorial Simple C Verse Client

jirihnidek edited this page Oct 13, 2014 · 5 revisions

This tutorial describes implementation of Verse client in C language using C API. Complete code created in this tutorial can be downloaded from this reposotory.

The simplest Verse client could look lite this and we will name it verse_client.c:

#include <verse.h>
#include <stdio.h>
#include <stdlib.h>

/* My session ID */
static uint8_t my_session_id = -1;

int main(void)
{
    int error_num;

    /* Send connect request to the server */
    error_num = vrs_send_connect_request("localhost",
        "12345",
        0,
        &my_session_id);

    return EXIT_SUCCESS;
}

If you installed verse library to the your system, then you can build previous code with following command:

gcc -o verse_client verse_client.c -lverse -lssl -lcrypto

It is compiled now, but it will not work and it will not do anything useful. Why? We have to register several callback functions that will be called, when asynchronous event happens. Callback functions are called, when packet with come command was received from Verse server. Every type of command has corresponding callback function. We needn't to implement all callback function. It is required to add only three basic functions. OK, lets add callback functions to our verse_client.c.

/* My callback function for user authentication */
void cb_receive_user_authenticate(const uint8_t session_id,
        const char *username,
        const uint8_t auth_methods_count,
        const uint8_t *methods)
{
    /* TODO: Do something useful here */
}

/* My callback function for connect accept */
void cb_receive_connect_accept(const uint8_t session_id,
        const uint16_t user_id,
        const uint32_t avatar_id)
{
    /* TODO: Do something useful here */
}

/* My callback function for connect terminate */
void cb_receive_connect_terminate(const uint8_t session_id,
        const uint8_t error_num)
{
    /* TODO: Do something useful here */
}

It is not everything. We will have to add some useful code to our callback function, but we have to say first to verse library about our callback function. We will use for this purpose register functions and we will add them to main() function:

int main(void)
{
    int error_num;

    /* Register basic callback functions */
    vrs_register_receive_user_authenticate(
        cb_receive_user_authenticate);
    vrs_register_receive_connect_accept(
        cb_receive_connect_accept);
    vrs_register_receive_connect_terminate(
        cb_receive_connect_terminate);

    /* Send connect request to the server */
    error_num = vrs_send_connect_request("localhost",
        "12345",
        0,
        &my_session_id);
}

It is necessary to add these register functions before vrs_send_connect_request() function is called.

The last thing we have to do is to periodically call function vrs_callback_update(). This function checks if Verse library received some commands and call registered functions.

    /* Send connect request to the server */
    error_num = vrs_send_connect_request("localhost",
        "12345",
        0,
        &my_session_id);

    if(error_num == VRS_SUCCESS) {
        /* Never ending loop */
        while(1) {
            vrs_callback_update(my_session_id);
            sleep(1);
        }
    }

Complete Verse client could look like this:

#include <verse.h>
#include <stdio.h>
#include <stdlib.h>

/* My session ID */
static uint8_t my_session_id = -1;

/* My callback function for user authentication */
void cb_receive_user_authenticate(const uint8_t session_id,
        const char *username,
        const uint8_t auth_methods_count,
        const uint8_t *methods)
{
    char name[64], *password;

    /* Get username, when it is requested */
    if(username == NULL) {
        printf("Username: ");
        scanf("%s", name);
        vrs_send_user_authenticate(session_id, name, 0, NULL);
    } else {
        /* We assume that VRS_UA_METHOD_PASSWORD is included
         * in array of methods */
        strcpy(name, username);
        /* Get password from user */
        password = getpass("Password: ");
        vrs_send_user_authenticate(session_id,
            name,
            VRS_UA_METHOD_PASSWORD,
            password);
    }
}

/* My callback function for connect accept */
void cb_receive_connect_accept(const uint8_t session_id,
        const uint16_t user_id,
        const uint32_t avatar_id)
{
    /* When we are connected, then terminate connection. */
    printf("Connection to Verse server established.\n");
    printf("Terminating this connection ...\n");
    vrs_send_connect_terminate(my_session_id);
}

/* My callback function for connect terminate */
void cb_receive_connect_terminate(const uint8_t session_id,
        const uint8_t error_num)
{
    /* Connection to Verse server was terminated */
    printf("Connection to Verse server terminated.\n");
    my_session_id = -1;
}

int main(void)
{
    int error_num;

    /* Register basic callback functions */
    vrs_register_receive_user_authenticate(
        cb_receive_user_authenticate);
    vrs_register_receive_connect_accept(
        cb_receive_connect_accept);
    vrs_register_receive_connect_terminate(
        cb_receive_connect_terminate);

    /* Send connect request to the server */
    error_num = vrs_send_connect_request("localhost",
        "12345",
        0,
        &my_session_id);
    if(error_num != VRS_SUCCESS) {
        printf("ERROR: %s\n", vrs_strerror(error_num));
        return EXIT_FAILURE;
    }

    /* Never ending loop */
    while(my_session_id != -1) {
        vrs_callback_update(my_session_id);
        sleep(1);
    }

    return EXIT_SUCCESS;
}
Clone this wiki locally