Set the state of a friend as offline if timeout goes without receiving
PONG. If PING is received, send PONG. If PONG is received, set state as
online.
#include <stdio.h>
#include "message.h"
#include <stdio.h>
#include "message.h"
+enum {
+ STATE_OFFLINE,
+ STATE_PINGED,
+ STATE_ONLINE,
+};
+
struct friend {
char *name;
char *address;
uint16_t port;
GInetSocketAddress *saddr;
struct friend {
char *name;
char *address;
uint16_t port;
GInetSocketAddress *saddr;
};
static GSocket *usock;
};
static GSocket *usock;
+void friend_timeout(struct friend *friend)
+{
+ if (friend->state == STATE_PINGED) {
+ friend->state = STATE_OFFLINE;
+ }
+}
+
+void friend_got_message(struct friend *friend, char *buffer, size_t len)
+{
+ if (len >= 4 && !strncmp(buffer, "PING", 4)) {
+ pong(friend);
+ } else if (len >= 4 && !strncmp(buffer, "PONG", 4)) {
+ friend->state = STATE_ONLINE;
+ }
+}
+
struct cache {
GList *friends;
};
struct cache {
GList *friends;
};
g_object_unref(addr);
cache->friends = g_list_append(cache->friends, friend);
ping(friend);
g_object_unref(addr);
cache->friends = g_list_append(cache->friends, friend);
ping(friend);
+ friend->state = STATE_PINGED;
+void friend_timeout(struct friend *friend);
+void friend_got_message(struct friend *friend, char *buffer, size_t len);
+
gboolean ping_timeout(gpointer data)
{
struct friend *friend = data;
gboolean ping_timeout(gpointer data)
{
struct friend *friend = data;
+ friend_timeout(friend);
return G_SOURCE_REMOVE;
}
return G_SOURCE_REMOVE;
}
friend = friend_get_by_address(iaddress, port);
if (friend) {
printf("got message from %s\n", friend_get_name(friend));
friend = friend_get_by_address(iaddress, port);
if (friend) {
printf("got message from %s\n", friend_get_name(friend));
- g_source_remove_by_user_data(friend);
+ friend_got_message(friend, buffer, len);
} else {
printf("could not find friend from address %s\n", g_inet_address_to_string(iaddress));
}
} else {
printf("could not find friend from address %s\n", g_inet_address_to_string(iaddress));
}
int ping(struct friend *friend)
{
int ping(struct friend *friend)
{
- friend_send_message(friend, ping, 4);
- g_timeout_add(2000, ping_timeout, friend);
+ err = friend_send_message(friend, ping, 4);
+ if (!err)
+ g_timeout_add(2000, ping_timeout, friend);
+ return err;
+}
+
+int pong(struct friend *friend)
+{
+ char pong[5] = "PONG";
+ return friend_send_message(friend, pong, 4);
int message_init(GSocket *sock);
int ping(struct friend *friend);
int message_init(GSocket *sock);
int ping(struct friend *friend);
+int pong(struct friend *friend);