NAME

on_connect - is invoked when a new connection is established.

SYNOPSIS

#include <game-carrier/server.h>

GC_ADAPTER_EVENT
GCT_INTPTR on_connect(
    GCT_INT app_id,
    GCT_INTPTR conn_handle,
    GCT_INT pid,
    GCT_CSTR rip,
    GCT_INT rport,
    GCT_CSTR lip,
    GCT_INT lport,
    GCT_CSTR udata);

Parameters:

  • app_id GCT_INT Unique identifier of the application.
  • conn_handle GCT_INTPTR Identifies the connection handle.
  • pid GCT_INT WebSocket protocol associated with the connection.
  • rip GCT_CSTR IP address of the remote client.
  • rport GCT_INT Remote port associated with the connection.
  • lip GCT_CSTR Local IP address of the server.
  • lport GCT_INT Local port of the server.
  • udata GCT_CSTR Additional data associated with the connection.

RETURN VALUE

If the application rejects a connection, it may return -1.

If the application accepts a connection, the on_connect function returns user data that will be associated with the connection. This value will be passed to other events that are related to the connection.

DESCRIPTION

The on_connect function is invoked by the gcs when a new connection is established. At this stage, the application can decide whether to accept or reject the connection. To reject a connection, the function may return a constant value of GC_DROP_CONNECTION (-1). In all other scenarios, the returned value will be treated as user data associated with the connection, which will be passed to other events associated with that connection. Typically, the application returns an index or the address of a structure linked to the connection at this point.

The app_id parameter represents the unique identifier of the application, whose value is used upon the invocation of the application_initialize function.

THe conn_handle parameter identifies the connection handle, which can be used for server API calls such as connectionAddMessage and others.

The pid parameter represents the protocol identifier associated with the connection. Possible values are GC_PROTOCOL_WSS (0) for WebSocket Secure and GC_PROTOCOL_WS (1) for WebSocket.

The rip parameter represents a string that contains the IP address of the remote client. This IP address corresponds to the client that initiated the connection with the server.

The rport parameter denotes the remote port number associated with the connection. It specifies the specific port on the remote client from which the connection was established.

The lip parameter represents a string that contains the local IP address of the server. This IP address corresponds to the network interface on the server where the connection is established.

The lport parameter refers to the local port number associated with the server-side connection. It specifies the specific port on the server where the connection is received and processed.

The udata parameter represents additional information associated with a connection and is stored as a text string in JSON format. When accepting a connection through the Cloudflare service, the JSON file contains a specific object named “cloudflare” that holds various details. Below, you will find the “cloudflare” object along with a description of its fields.

“cloudflare” Object

@include gc_server_on_connect_json_example.json

Parameters:

version - Represents the version of the Cloudflare protocol. inet_proto - Specifies the internet protocol used for the connection (e.g., TCP4). client - Provides details about the client-side, including the client’s IP address and port number. proxy - Contains information about the proxy server, including its IP address and port number header_size - Indicates the size of the headers associated with the Cloudflare connection.

Refer to the Cloudflare Protocol. documentation for more details.

For more infomation about Cloudflare configuration in the Game Carrier, see Game Carrier Configuration

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

on_disconnect, on_message