NAME

s2sCreate - create new server to server connection.

SYNOPSIS

#include <game-carrier/server.h>

typedef GCT_INT (GC_CORE_API *S2SCreate)(
    GCT_INT adapter,
    GCT_INTPTR s2s_user,
    GCT_INT proto,
    GCT_PTR host,
    GCT_INT port,
    GCT_PTR app_name,
    struct client_events * events);

typedef struct s2sCreate {
    /* ... Some fields ... */
    S2SCreate s2sCreate;
    /* ... Some fields ... */
}

Parameters:

  • adapter GCT_INT Adapter id
  • s2s_user GCT_INTPTR User data associated with a connection.
  • proto GCT_INT WebSocket protocol version.
  • host GCT_CSTR Domain name or IP address of the server.
  • port GCT_INT Server port number.
  • app_name GCT_CSTR Application name.
  • events pointer to the client_events struct.

RETURN VALUE

Returns 0 if the operation is successful.

Standard errno codes like EINVAL or ENOMEM are returned if creation/allocation fails.

DESCRIPTION

The s2sCreate function establishes a connection with a Game Carrier server application and returns an error code where 0 means success.

The adapter_id parameter is the unique identifier of the adapter.

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.

When proto parameter is set to GC_PROTOCOL_WSS, this method will use the WebSocket Secure(WSS) protocol. Otherwise, when set to GC_PROTOCOL_WS (1), an unencrypted version of WebSocket is used.

The host parameter represents the fully qualified domain name(FQDN) of the game server, for instance "https://yourgame.server.com", or an IP address string.

The port parameter specifies the port number to establish the connection with the server. The port number must be set during the configuration of the game server.

The app_name parameter specifies the unique application name. This parameter is used to distinguish the app you want to connect to from other apps running on the server. By passing NULL to this parameter, you instruct the function to connect to a default application associated with a specific host/port configuration set in the server’s config file.

The events parameter specifies the pointer to the client_events struct.

You must invoke this function only if the application_start event has been received.

If s2sCreate fails and returns nonzero error code, no events will occur. However, if s2sCreate succeeds (0 is returned), the on_client_connect or on_client_connection_error event will be called subsequently.

The connection descriptor representing a handle to the client session that has established will be received in on_client_connect event. This handle is represented as the s2s_handle parameter in other Server API functions.

In case of client library the analogeous function is gc_client_start.

EXAMPLE

#include <game-carrier/server.h>

#include <stdio.h>

static struct core_api api;

#define STAT_SERVER 1
#define CACHE_SERVER 2

GCT_INT adapter_id;
GCT_INTPTR s2s_stat_handle, s2s_cache_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 == STAT_SERVER) {
        api.logMessage(GCL_NOTICE, "Connected to the stat server");
        s2s_stat_handle = handle;
        api.s2sDestroy(s2s_stat_handle);
        return;
    }

    if (conn_user == CACHE_SERVER) {
        api.logMessage(GCL_NOTICE, "Connected to the cache server");
        s2s_cache_handle = handle;
        api.s2sDestroy(s2s_cache_handle);
        return;
    }

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

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

    if (conn_user == STAT_SERVER) {
        snprintf(buf, sizeof(buf), "Failed to connect to the stat server: %s.", reason);
        api.logMessage(GCL_ERR, buf);
        return;
    }

    if (conn_user == CACHE_SERVER) {
        snprintf(buf, sizeof(buf), "Failed to connect to the cache server: %s", reason);
        api.logMessage(GCL_ERR, buf);
        return;
    }

    snprintf(buf, sizeof(buf), "??? Failed to connect to an unknown server: %s", reason);
    api.logMessage(GCL_ERR, buf);
}

void on_client_disconnect(GCT_INTPTR conn_user)
{
    if (conn_user == STAT_SERVER) {
        api.logMessage(GCL_NOTICE, "Disconect from stat server");
        return;
    }

    if (conn_user == CACHE_SERVER) {
        api.logMessage(GCL_NOTICE, "Disconect from cache server");
        return;
    }

    api.logMessage(GCL_ERR, "??? Disconect from unknown server");
}

GC_ADAPTER_EVENT
void application_start(GCT_INT app_id)
{
    int status;

    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;

    status = api.s2sCreate(adapter_id, STAT_SERVER, GC_PROTOCOL_WSS, "stat.example.com", 7681, "stat", &events);
    if (status != 0) {
        api.logMessage(GCL_ERR, "Failed to connect to the game server.");
    }

    status = api.s2sCreate(adapter_id, CACHE_SERVER, GC_PROTOCOL_WSS, "cache.example.com", 7681, "cache", &events);
    if (status != 0) {
        api.logMessage(GCL_ERR, "Failed to connect to the lobby server.");
    }
}

SEE ALSO

gc_protocols, on_client_connect, on_client_connection_error