Skip to content

Instantly share code, notes, and snippets.

@dkorolev
Created August 12, 2024 09:21
Show Gist options
  • Save dkorolev/20f63789b12883f0f255c829f8cdeaa3 to your computer and use it in GitHub Desktop.
Save dkorolev/20f63789b12883f0f255c829f8cdeaa3 to your computer and use it in GitHub Desktop.
The `echo.c` using the `connection_context` ref. https://github.com/Theldus/wsServer/pull/93
/*
* Copyright (C) 2016-2023 Davidson Francis <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <ws.h>
/**
* @dir examples/
* @brief wsServer examples folder
*/
/*
* @dir examples/echo
* @brief Echo example directory.
* @file echo.c
* @brief Simple echo example.
*/
/**
* @brief To demonstrate the use of server and client contexts.
*/
static int base_pointer_to_suppress_warning;
struct counter_with_mutex
{
pthread_mutex_t mutex;
int *pointer_ahead_of_base_pointer;
};
/**
* @brief Called when a client connects to the server.
*
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*/
void onopen(ws_cli_conn_t *client)
{
char *cli, *port;
struct counter_with_mutex* server_context = ws_get_server_context(client);
pthread_mutex_lock(&server_context->mutex);
++server_context->pointer_ahead_of_base_pointer;
ws_set_connection_context(client, server_context->pointer_ahead_of_base_pointer);
pthread_mutex_unlock(&server_context->mutex);
cli = ws_getaddress(client);
port = ws_getport(client);
#ifndef DISABLE_VERBOSE
printf("Connection opened, addr: %s, port: %s\n", cli, port);
#endif
}
/**
* @brief Called when a client disconnects to the server.
*
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*/
void onclose(ws_cli_conn_t *client)
{
char *cli;
cli = ws_getaddress(client);
#ifndef DISABLE_VERBOSE
printf("Connection closed, addr: %s\n", cli);
#endif
}
/**
* @brief Called when a client connects to the server.
*
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*
* @param msg Received message, this message can be a text
* or binary message.
*
* @param size Message size (in bytes).
*
* @param type Message type.
*/
void onmessage(ws_cli_conn_t *client,
const unsigned char *msg, uint64_t size, int type)
{
char *cli;
int my_counter_value;
cli = ws_getaddress(client);
my_counter_value = ((int*)ws_get_connection_context(client)) - &base_pointer_to_suppress_warning;
#ifndef DISABLE_VERBOSE
printf("I (client index %d) receive a message: %s (size: %" PRId64 ", type: %d), from: %s\n",
my_counter_value, msg, size, type, cli);
#endif
/**
* Mimicks the same frame type received and re-send it again
*
* Please note that we could just use a ws_sendframe_txt()
* or ws_sendframe_bin() here, but we're just being safe
* and re-sending the very same frame type and content
* again.
*
* Alternative functions:
* ws_sendframe()
* ws_sendframe_txt()
* ws_sendframe_txt_bcast()
* ws_sendframe_bin()
* ws_sendframe_bin_bcast()
*/
ws_sendframe_bcast(8080, (char *)msg, size, type);
}
/**
* @brief Main routine.
*
* @note After invoking @ref ws_socket, this routine never returns,
* unless if invoked from a different thread.
*/
int main(void)
{
struct counter_with_mutex counter;
pthread_mutex_init(&counter.mutex, NULL);
counter.pointer_ahead_of_base_pointer = &base_pointer_to_suppress_warning;
ws_socket(&(struct ws_server){
/*
* Bind host:
* localhost -> localhost/127.0.0.1
* 0.0.0.0 -> global IPv4
* :: -> global IPv4+IPv6 (DualStack)
*/
.host = "0.0.0.0",
.port = 8080,
.thread_loop = 0,
.timeout_ms = 1000,
.evs.onopen = &onopen,
.evs.onclose = &onclose,
.evs.onmessage = &onmessage,
.context = &counter
});
/*
* If you want to execute code past ws_socket(), set
* .thread_loop to '1'.
*/
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment