NAME

on_client_message_sent - event is triggered when a message is delivered to the operating system.

SYNOPSIS

#include <game-carrier/common.h>

typedef void (*OnClientMessageSent)(GCT_INTPTR conn_user, GCT_INTPTR cookie, GCT_SIZE len, int status);

typedef struct on_client_message_sent {
    /* ... Some fields ... */
    OnClientMessageSent on_client_message_sent;
    /* ... Some fields ... */
}

Parameters:

  • conn_user GCT_INTPTR User data associated with the connection.
  • cookie GCT_INTPTR A pointer to the user data.
  • len GCT_SIZE The length of the received message in bytes.
  • status int The error code of the write operation.

RETURN VALUE

None.

DESCRIPTION

The on_client_message_sent event is a member of the client_events struct. It is triggered when a message is successfully delivered to the operating system. However, it does not guarantee that the server application will receive the message. This event occurs after invoking the s2sAddMessage function.

The conn_user parameter represents the user-defined data that is associated with a connection. This data is passed to all event handlers that are defined in the client_events struct. This parameter allows the user to find their own connection-related data. It could be a pointer to a structure allocated before creation a connection, or an index in some container. If the user has created multiple connections, they could use different conn_user values for each connection and then use that value in the event handlers to determine which connection the event is associated with.

The cookie parameter allows associating the user-specific data with the message and can be utilized for custom handling or identification purposes when the on_client_message_sent event is triggered.

The len parameter ndicates the length of the received message in bytes.

The status parameter represents the error code of the write operation. A value of 0 indicates that there is no error. Typically, it corresponds to one of the standard values that can be stored in the errno variable.

It is guaranteed that every s2sAddMessage call will be followed by the corresponding on_client_message_sent event.

EXAMPLE

#include <game-carrier/server.h>

#include <stdio.h>
#include <string.h>

/**
 * The example below connects to a server,
 * waits for a message and then it disconnects.
 **/

static struct core_api api;

#define S2S_USER_INDEX  1
#define MAGIC_COOKIE   42

GCT_INT adapter_id;
GCT_INTPTR s2s_handle;

GC_ADAPTER_EVENT
GCT_INT adapter_initialize(
    GCT_INT id,
    struct core_api * core_api,
    GCT_CPTR load_path)
{
    adapter_id = id;
    api = *core_api;
}

void on_client_connect(GCT_INTPTR conn_user, GCT_INTPTR handle)
{
    if (conn_user == S2S_USER_INDEX) {
        api.logMessage(GCL_NOTICE, "S2S connected");
        s2s_handle = handle;
        char * msg = "Hello!";
        api.s2sAddMessage(s2s_handle, msg, strlen(msg), MAGIC_COOKIE);
        return;
    }

    api.logMessage(GCL_ERR, "??? S2S connected to an unknown server");
}

void on_client_connection_error(GCT_INTPTR conn_user, GCT_CSTR reason)
{
    char buf[256];

    if (conn_user == S2S_USER_INDEX) {
        snprintf(buf, sizeof(buf), "S2S connection failed: %s.", reason);
        api.logMessage(GCL_ERR, buf);
        return;
    }

    snprintf(buf, sizeof(buf), "??? Unknown S2S connection failed:  %s", reason);
    api.logMessage(GCL_ERR, buf);
}

void on_client_disconnect(GCT_INTPTR conn_user)
{
    if (conn_user == S2S_USER_INDEX) {
        api.logMessage(GCL_NOTICE, "S2S disconect");
        return;
    }

    api.logMessage(GCL_ERR, "??? Unknown S2S disconect");
}

void on_client_message(
    GCT_INTPTR conn_user, GCT_PTR data, GCT_SIZE len)
{
    char buf[256];

    if (conn_user == S2S_USER_INDEX) {
        snprintf(buf, sizeof(buf), "S2S message: %s", (char*)data);
        api.logMessage(GCL_NOTICE, buf);
        api.s2sDestroy(s2s_handle);
        return;
    }

    snprintf(buf, sizeof(buf), "??? Unknown S2S message: %s", (char*)data);
    api.logMessage(GCL_ERR, buf);
}

void on_client_message_sent(
    GCT_INTPTR conn_user,
    GCT_INTPTR cookie,
    GCT_SIZE len,
    GCT_INT status)
{
    char buf[256];

    if (conn_user != S2S_USER_INDEX) {
        snprintf(buf, sizeof(buf), "??? Unknown S2S message sent");
        api.logMessage(GCL_ERR, buf);
        return;
    }

    if (cookie != MAGIC_COOKIE) {
        snprintf(buf, sizeof(buf), "??? Unexpected cookie received: " PRId64, cookie);
        api.logMessage(GCL_ERR, buf);
        return;
    }

    if (status != 0) {
        snprintf(buf, sizeof(buf), "S2S message failed to send: %d", status);
        api.logMessage(GCL_ERR, buf);
        return;
    }

    api.logMessage(GCL_NOTICE, "S2S message sent OK");
}

GC_ADAPTER_EVENT
void application_start(GCT_INT app_id)
{
    ClientEvents events;
    events.on_client_connect = on_client_connect;
    events.on_client_connection_error = on_client_connection_error;
    events.on_client_disconnect = on_client_disconnect;
    events.on_client_message = on_client_message;
    events.on_client_message_sent = on_client_message_sent;

    int status = api.s2sCreate(adapter_id, S2S_USER_INDEX, GC_PROTOCOL_WSS, "server.example.com", 7681, "server", &events);
    if (status != 0) {
        api.logMessage(GCL_ERR, "Failed to allocate S2S.");
    }
}

SEE ALSO

s2sCreate, s2sAddMessage