detect disconnect and reconnect (channels still missing)

This commit is contained in:
Green Sky 2024-06-18 12:12:08 +02:00
parent 0be741947c
commit 3cb37e33a2
No known key found for this signature in database
3 changed files with 116 additions and 64 deletions

View File

@ -63,8 +63,7 @@ SOLANA_PLUGIN_EXPORT void solana_plugin_stop(void) {
}
SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float delta) {
(void)delta;
g_ircc->iterate(); // TODO: return interval, respect dcc etc
g_ircc->iterate(delta); // TODO: return interval, respect dcc etc
return 1.f; // expect atleast once per sec
}

View File

@ -26,6 +26,7 @@ void IRCClient1::on_event_numeric(irc_session_t* session, unsigned int event, co
auto ircc = static_cast<IRCClient1*>(irc_get_ctx(session));
ircc->dispatch(IRCClient_Event::NUMERIC, IRCClient::Events::Numeric{event, origin, params_view});
ircc->_event_fired = true;
}
IRCClient1::IRCClient1(
@ -77,7 +78,105 @@ IRCClient1::IRCClient1(
irc_option_set(_irc_session, LIBIRC_OPTION_STRIPNICKS);
irc_option_set(_irc_session, LIBIRC_OPTION_SSL_NO_VERIFY); // why
connectSession();
}
IRCClient1::~IRCClient1(void) {
irc_destroy_session(_irc_session);
}
// tmp
void IRCClient1::run(void) {
if (irc_run(_irc_session) != 0) {
std::cerr << "error failed to run: " << irc_strerror(irc_errno(_irc_session)) << "\n";
}
}
float IRCClient1::iterate(float delta) {
//if ( session->state != LIBIRC_STATE_CONNECTING )
//{
//session->lasterror = LIBIRC_ERR_STATE;
//return 1;
//}
if (!irc_is_connected(_irc_session)) {
if (_try_connecting_state) {
// try to connect, every 20sec
_try_connecting_cooldown -= delta;
if (_try_connecting_cooldown <= 0.f) {
std::cerr << "IRCC: trying to connect\n";
connectSession();
}
} else {
std::cerr << "IRCC error: not connected, trying to reconnect\n";
connectSession(); // potentially enters trying phase
}
return 0.5f;
}
_event_fired = false;
struct timeval tv;
fd_set in_set, out_set;
int maxfd = 0;
//tv.tv_usec = 20000; // 20ms
tv.tv_usec = 1000; // 1ms
tv.tv_sec = 0;
// Init sets
FD_ZERO(&in_set);
FD_ZERO(&out_set);
if (irc_add_select_descriptors(_irc_session, &in_set, &out_set, &maxfd) != 0) {
std::cerr << "IRCC error: adding select descriptors\n";
}
if (select(maxfd + 1, &in_set, &out_set, 0, &tv) < 0) {
std::cerr << "IRCC error: select returned error\n";
#if 0
if (socket_error() == EINTR) {
//continue;
return;
}
#endif
//session->lasterror = LIBIRC_ERR_TERMINATED;
//return 1;
return 0.1f;
}
if (irc_process_select_descriptors(_irc_session, &in_set, &out_set) != 0) {
std::cerr << "IRCC error: processing socket select\n";
//return 1;
}
// TODO: handle dcc
if (_event_fired) {
return 0.1f;
} else {
return 1.f;
}
}
irc_session_t* IRCClient1::getSession(void) {
return _irc_session;
}
const std::string_view IRCClient1::getServerName(void) const {
return _server_name;
}
void IRCClient1::connectSession(void) {
_try_connecting_state = true;
_try_connecting_cooldown = 20.f;
// reset connection
// only closes potentially open sockets and sets state to init
// nothing else is touched
irc_disconnect(_irc_session);
// TODO: do we need to set this every time?
if (!_conf.has_string("IRCClient", "server")) {
std::cerr << "IRCC error: no irc server in config!!\n";
throw std::runtime_error("missing server in config");
@ -111,70 +210,14 @@ IRCClient1::IRCClient1(
}
if (irc_connect(_irc_session, server.c_str(), port, nullptr, nick.c_str(), username.c_str(), realname.c_str()) != 0) {
std::cerr << "error failed to connect: (" << irc_errno(_irc_session) << ") " << irc_strerror(irc_errno(_irc_session)) << "\n";
throw std::runtime_error("failed to connect to irc");
}
}
std::cerr << "IRCC error: failed to connect: (" << irc_errno(_irc_session) << ") " << irc_strerror(irc_errno(_irc_session)) << "\n";
IRCClient1::~IRCClient1(void) {
irc_destroy_session(_irc_session);
}
irc_disconnect(_irc_session);
// tmp
void IRCClient1::run(void) {
if (irc_run(_irc_session) != 0) {
std::cerr << "error failed to run: " << irc_strerror(irc_errno(_irc_session)) << "\n";
}
}
void IRCClient1::iterate(void) {
//if ( session->state != LIBIRC_STATE_CONNECTING )
//{
//session->lasterror = LIBIRC_ERR_STATE;
//return 1;
//}
if (!irc_is_connected(_irc_session)) {
//throw std::runtime_error("failed to connect to irc");
return;
}
struct timeval tv;
fd_set in_set, out_set;
int maxfd = 0;
//tv.tv_usec = 20000; // 20ms
tv.tv_usec = 1000; // 1ms
tv.tv_sec = 0;
// Init sets
FD_ZERO (&in_set);
FD_ZERO (&out_set);
irc_add_select_descriptors(_irc_session, &in_set, &out_set, &maxfd);
if (select(maxfd + 1, &in_set, &out_set, 0, &tv) < 0)
{
#if 0
if (socket_error() == EINTR) {
//continue;
return;
}
#endif
//session->lasterror = LIBIRC_ERR_TERMINATED;
//return 1;
return;
_try_connecting_state = false;
}
if (irc_process_select_descriptors(_irc_session, &in_set, &out_set)) {
//return 1;
}
}
irc_session_t* IRCClient1::getSession(void) {
return _irc_session;
}
const std::string_view IRCClient1::getServerName(void) const {
return _server_name;
}

View File

@ -170,7 +170,11 @@ using IRCClientEventProviderI = EventProviderI<IRCClientEventI>;
class IRCClient1 : public IRCClientEventProviderI {
ConfigModelI& _conf;
irc_session_t* _irc_session = nullptr;
irc_session_t* _irc_session {nullptr};
bool _try_connecting_state {false};
float _try_connecting_cooldown {0.f};
bool _event_fired {false};
std::string _server_name; // name of the irc network this iirc is connected to
@ -181,9 +185,10 @@ class IRCClient1 : public IRCClientEventProviderI {
~IRCClient1(void);
// tmp
void run(void);
void iterate(void);
float iterate(float delta);
// raw access
irc_session_t* getSession(void);
@ -193,6 +198,10 @@ class IRCClient1 : public IRCClientEventProviderI {
// join
void join(std::string_view channel);
private:
// connects an already existing session
void connectSession(void);
private: // callbacks for libircclient
static void on_event_numeric(irc_session_t* session, unsigned int event, const char* origin, const char** params, unsigned int count);
@ -220,6 +229,7 @@ class IRCClient1 : public IRCClientEventProviderI {
assert(ircc != nullptr);
ircc->dispatch(event_type_enum, EventType{origin, params_view});
ircc->_event_fired = true;
}
};