OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogserver / opencog / network / NetworkServer.h

101 lines · c ref:
/*
 * opencog/network/NetworkServer.h
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * Written by Andre Senna <senna@vettalabs.com>
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#ifndef _OPENCOG_SIMPLE_NETWORK_SERVER_H
#define _OPENCOG_SIMPLE_NETWORK_SERVER_H

#include <atomic>
#include <functional>
#include <list>
#include <mutex>
#include <queue>
#include <string>
#include <thread>

#include <asio.hpp>
#include <opencog/network/ServerSocket.h>
#include <opencog/network/SocketManager.h>

namespace opencog
{
/** \addtogroup grp_server
 *  @{
 */

/**
 * This class implements the entity responsible for managing the
 * server's network server.
 *
 * The network server runs on its own thread (thus freeing the server's
 * main loop to deal with requests only). It may be enabled/disabled at
 * will so that a server may run in networkless mode if desired.
 *
 * The network server supports only one server socket. Client applications
 * should use the 'start' method to start listening to a port.
 * Currently, the network server doesn't
 * support selecting the network interface that the server socket will bind to
 * (server sockets bind to all interfaces in dual-stack mode, accepting both
 * IPv4 and IPv6 connections). Thus, server sockets are identified/selected
 * by the port they bind to.
 */
class NetworkServer
{
protected:
    std::string _name;
    short _port;
    std::atomic_bool _running;
    asio::io_context _io_service;
    asio::ip::tcp::acceptor _acceptor;
    std::thread* _listener_thread;

    /** Track all handler threads for proper cleanup */
    std::mutex _handler_threads_mtx;
    std::list<std::thread*> _handler_threads;

    /** Socket manager for tracking and managing all sockets (shared across all servers) */
    SocketManager* _socket_manager;

    /** The network server's main listener thread.  */
    void listen();
    std::function<ServerSocket*(SocketManager*)> _getServer;

    /** monitoring stats */
    time_t _start_time;
    time_t _last_connect;
    size_t _nconnections;

public:

    /**
     * Starts the NetworkServer in a new thread.
     * The socket listen happens in the new thread.
     */
    NetworkServer(unsigned short port, const char* name, SocketManager* mgr);
    ~NetworkServer();

    /** Start and stop the server */
    void run(std::function<ServerSocket*(SocketManager*)>);
    void stop_listening();
    void join_threads();

    /** Get the socket manager */
    SocketManager* get_socket_manager() { return _socket_manager; }

    /** Get server start time for stats display */
    time_t get_start_time() const { return _start_time; }
    const char* get_name() const { return _name.c_str(); }

    /** Get the port this server is listening on */
    short getPort() const { return _port; }
}; // class

/** @}*/
}  // namespace

#endif // _OPENCOG_SIMPLE_NETWORK_SERVER_H