-
Notifications
You must be signed in to change notification settings - Fork 0
/
message_dispatcher.c
104 lines (89 loc) · 3.52 KB
/
message_dispatcher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
Written by Devin Headrick
Summer 2024
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <poll.h>
#include <fcntl.h>
#include "connection.h"
#define POLLING_TIMEOUT_MS 1000
int main(int argc, char *argv[])
{
char buffer[MESSAGE_UNIT_SIZE] = {0}; // Single buffer for reading and writing between clients
int ret = 0; // used for assessing returns of various fxn calls
int ready; // how many fd are ready from the poll (have return event)
int num_components = 2;
ComponentStruct *dfgm_handler = component_factory("dfgm_handler", DFGM);
ComponentStruct *coms_handler = component_factory("coms_handler", COMS);
// Array of pointers to components the message dispatcher interacts with
ComponentStruct *components[2] = {dfgm_handler, coms_handler};
nfds_t nfds = (unsigned long int)num_components; // num of fds we are polling
struct pollfd *pfds; // fd we are polling
pfds = (struct pollfd *)calloc(nfds, sizeof(struct pollfd));
for (nfds_t i = 0; i < num_components; i++)
{
pfds[i].fd = components[i]->conn_socket_fd;
printf("pfds %lu : %d\n", i, pfds[i].fd);
pfds[i].events = POLLIN;
}
for (;;)
{
ready = poll(pfds, nfds, POLLING_TIMEOUT_MS);
if (ready == -1)
{
handle_error("polling failed\n");
}
// Loop over fds we are polling, check return event setting
for (int i = 0; i < nfds; i++)
{
if (pfds[i].revents != 0 && pfds[i].revents & POLLIN)
{
// IF we are waiting for a client to send a connection request
if (components[i]->connected == 0)
{
// Accept this conn request and get the data socket fd (returned from accept())
printf("WE GOT A CONNECTION \n");
accept_incoming_client_conn_request(components[i], &pfds[i]);
}
// IF we are waiting for incoming data from a connected client
else
{
if (read_data_socket(components[i], &pfds[i], buffer) == 0)
{
continue;
}
if (!strncmp(buffer, "DOWN", sizeof(buffer)))
{
printf("Received DOWN - server shutting down \n");
goto CleanEnd;
}
int dest_id = get_msg_dest_id(buffer);
// Now use the msg destination ID to determine what component (socket) to send the message to
// loop over components array of pointers - whichever component id enum matches the read dest id is what we are writing to
int dest_comp_fd = get_fd_from_id(components, num_components, dest_id);
if (dest_comp_fd > -1)
{
ret = write(dest_comp_fd, buffer, sizeof(buffer));
if (ret < 0)
{
printf("Write failed \n");
}
}
memset(buffer, 0, MESSAGE_UNIT_SIZE); // clear read buffer after handling data
}
}
}
}
CleanEnd:
free(pfds);
for (int i = 0; i < num_components; i++)
{
free(components[i]);
}
exit(EXIT_SUCCESS);
}