Created
August 12, 2024 09:21
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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