NAME

on_message_sent - is invoked by the gcs when a message is delivered to the operating system.

SYNOPSIS

#include <game-carrier/server.h>

GC_ADAPTER_EVENT
void on_message_sent(
    GCT_INTPTR conn_user,
    GCT_INTPTR cookie,
    GCT_SIZE len,
    GCT_INT status);

Parameters:

  • conn_user GCT_INTPTR User data associated with the connection.
  • cookie GCT_INTPTR User data associated with the message.
  • len GCT_SIZE The length of the message.
  • status GCT_INT The message status, 0 on success.

RETURN VALUE

None.

DESCRIPTION

The on_message_sent function is invoked by the gcs when a message is successfully delivered to the operating system. However, there is no guarantee that the client application will receive the message. This function is called after the connectionAddMessage call.

The on_message_sent function is executed within the worker thread context of the gcs. All connection events are serialized, eliminating the need for synchronization primitives. The connection is not bound to a specific thread in the worker thread pool, meaning that different threads may handle connection events.

The conn_user parameter represents the user data associated with the connection, which is the same value returned by the on_connect call.

The cookie parameter represents the user data associated with the message, which is the same value passed to the connectionAddMessage call.

The len parameter indicates the length of the message.

The status parameter indicates the status of the message. If the message was successfully delivered to the operating system, the status is 0. Otherwise, a non-zero error code indicates that the message was not delivered to the operating system.

EXAMPLE

#include <game-carrier/server.h>

#include <stdlib.h>
#include <string.h>

#define COOKIE_MAGIC  0xFACE

static struct core_api api;

struct connection_data {
    GCT_INTPTR handle;
    /* Another user data asociated with connection */
};

int is_good_connection(GCT_INT rport, GCT_CSTR rip, GCT_CSTR udata);

GC_ADAPTER_EVENT
int adapter_initialize(int id, struct core_api *core_api, const void *load_path)
{
    api = *core_api;
    return 0;
}

GC_ADAPTER_EVENT
GCT_INTPTR on_connect(
    GCT_INT app_id,
    GCT_INTPTR handle,
    GCT_INT pid,
    GCT_CSTR rip,
    GCT_INT rport,
    GCT_CSTR lip,
    GCT_INT lport,
    GCT_CSTR udata)
{
    /* Check if this connection can be accepted */
    if (!is_good_connection(rport, rip, udata)) {
        return GC_DROP_CONNECTION;
    }

    /* Allocate user data */
    struct connection_data * conn = malloc(sizeof(struct connection_data));
    if (conn == NULL) {
        return GC_DROP_CONNECTION;
    }

    /* Save connection handle */
    conn->handle = handle;

    /* Send greetings */
    const char * msg = "Hello!";
    int status = api.connectionAddMessage(handle, msg, strlen(msg), COOKIE_MAGIC);
    if (status != 0) {
        api.logMessage(GCL_ERR, "Failed to send message");
        return GC_DROP_CONNECTION;
    }

    /* Return user data */
    return (GCT_INTPTR)conn;
}

GC_ADAPTER_EVENT
void on_message_sent(
    GCT_INTPTR conn_user,
    GCT_INTPTR cookie,
    GCT_SIZE len,
    GCT_INT status)
{
    if (cookie != COOKIE_MAGIC) {
        api.logMessage(GCL_ERR, "Invalid cookie!");
        return;
    }
}

SEE ALSO

connectionAddMessage