Информация об изменениях

Сообщение Re[8]: Вопрос НЕ про Poco! Любая простая net библиотека от 03.02.2017 9:51

Изменено 03.02.2017 9:57 Мёртвый Даун

Re[8]: Вопрос НЕ про Poco! Любая простая net библиотека
Здравствуйте, so5team, Вы писали:

Именно с этим я уже и разобрался... EchoServer там единственный пример, но опять же сервера (почему? почему нигде нет примера клиента? причем не только в Poco). Я правда эту срань под названием Poco уже удалил, и больше никогда в жизни не поставлю, но раз уж вы ответили, то продолжу только изза этого...
Попытался создать пример, который бы вписался в архитектуру моего проекта, но разумеется это дерьмо не работает и никогда не может работать, потому что это же Poco.
class MySocketReactor: public Poco::Net::SocketReactor
{
public:
    // чтобы проц не грузить
    void onBusy() {
        Poco::Thread::yield();
        Poco::Thread::sleep(1);
    }
};

class MyClientServiceHandler
{
public:
    MyClientServiceHandler(Poco::Net::StreamSocket& socket, MySocketReactor& reactor)
: m_socket(socket)
, m_reactor(reactor)
, m_OnReadable(*this, &MyClientServiceHandler::OnReadable)
, m_OnWritable(*this, &MyClientServiceHandler::OnWritable)
, m_OnTimeout(*this, &MyClientServiceHandler::OnTimeout)
, m_sendBuffer(1024, true)
, m_receiveBuffer(1024, true)
{
    m_socketReactorThread.start(m_reactor);
    
    m_reactor.addEventHandler(m_socket, m_OnReadable);
    m_reactor.addEventHandler(m_socket, m_OnWritable);
    m_reactor.addEventHandler(m_socket, m_OnTimeout);
    
    m_sendBuffer.readable += Poco::delegate(this, &MyClientServiceHandler::OnSend);
        m_receiveBuffer.writable += Poco::delegate(this, &MyClientServiceHandler::OnReceive);
}

~MyClientServiceHandler()
{
    m_reactor.removeEventHandler(m_socket, m_OnReadable);
    m_reactor.removeEventHandler(m_socket, m_OnWritable);
    m_reactor.removeEventHandler(m_socket, m_OnTimeout);
    
    m_sendBuffer.readable -= Poco::delegate(this, &MyClientServiceHandler::OnSend);
    m_receiveBuffer.writable -= Poco::delegate(this, &MyClientServiceHandler::OnReceive);
    
    m_reactor.stop();
    m_socketReactorThread.join();
}
    
void OnReadable(Poco::Net::ReadableNotification* notification)
{
    notification->release();
    
    try {
        int receiveBytes = m_socket.receiveBytes(m_receiveBuffer);
        if (receiveBytes > 0) {
            // здесь делаем важную работу...
        } else {
            delete this;
        }
    } catch (Poco::Exception &e) {
        delete this;
    }
}

void OnWritable(Poco::Net::WritableNotification* notification);

void OnTimeout(Poco::Net::TimeoutNotification* notification)
{
    notification->release();
    m_reactor.stop();
    delete this;
}
    
void OnSend(bool &flag)
{
    if (flag)
        m_reactor.addEventHandler(m_socket, m_OnWritable);
    else
        m_reactor.removeEventHandler(m_socket, m_OnWritable);
}
void OnReceive(bool &flag);

void send(const MyMessage &buffer)
{
        // где вызвать этот метод, если у меня нет экземляра клиента?
    m_sendBuffer.copy(buffer.data(), buffer.size());
}
private:
    Poco::Net::StreamSocket m_socket;
    MySocketReactor &m_reactor;
    Poco::Observer<MyClientServiceHandler, Poco::Net::ReadableNotification> m_OnReadable;
    Poco::Observer<MyClientServiceHandler, Poco::Net::WritableNotification> m_OnWritable;
    Poco::Observer<MyClientServiceHandler, Poco::Net::TimeoutNotification>  m_OnTimeout;

    Poco::Thread m_socketReactorThread;
    
    Poco::FIFOBuffer m_sendBuffer;   // собственно основная замута была ради этого, мне нужны буферы которые оповещают, и хэндлеры
    Poco::FIFOBuffer m_receiveBuffer;
    
    friend std::ostream& operator << (std::ostream&, const MyClientServiceHandler&);
};

class MySocketConnector: public Poco::Net::SocketConnector<MyClientServiceHandler>
{
public:
    MySocketConnector(Poco::Net::SocketAddress& address, MySocketReactor& reactor)
: SocketConnector<MyClientServiceHandler>(address, reactor)
{
    reactor.addEventHandler(socket(), Poco::Observer<MySocketConnector, Poco::Net::TimeoutNotification>(*this, &MySocketConnector::OnTimeout));
    reactor.addEventHandler(socket(), Poco::Observer<MySocketConnector, Poco::Net::ShutdownNotification>(*this, &MySocketConnector::OnShutdown));
}
    void OnShutdown(Poco::Net::ShutdownNotification* notification);
    void OnTimeout(Poco::Net::TimeoutNotification* notification);
    void OnError(int error);

protected:
    MyClientServiceHandler* createServiceHandler() {
    return new MyClientServiceHandler(_socket, *_pReactor);
    }
};

// Используем

class Connection
{
public:
    Connection() : m_connector(m_socketAddress, m_reactor) {}
private:
    Poco::Net::SocketAddress m_socketAddress;
    Poco::Net::SocketReactor m_reactor;
    MySocketConnector m_connector; // как это дерьмо использовать?
}


В результате у меня нигде нет доступа к объекту класса MyClientServiceHandler. Как мне положить в исходящий буфер?
Re[8]: Вопрос НЕ про Poco! Любая простая net библиотека
Здравствуйте, so5team, Вы писали:

Именно с этим я уже и разобрался... EchoServer там единственный пример, но опять же сервера (почему? почему нигде нет примера клиента? причем не только в Poco). Я правда эту срань под названием Poco уже удалил, и больше никогда в жизни не поставлю, но раз уж вы ответили, то продолжу только изза этого...
Попытался создать пример, который бы вписался в архитектуру моего проекта, но разумеется это дерьмо не работает и никогда не может работать, потому что это же Poco.
class MySocketReactor: public Poco::Net::SocketReactor
{
public:
    // чтобы проц не грузить
    void onBusy() {
        Poco::Thread::yield();
        Poco::Thread::sleep(1);
    }
};

class MyClientServiceHandler
{
public:
    MyClientServiceHandler(Poco::Net::StreamSocket& socket, MySocketReactor& reactor)
: m_socket(socket)
, m_reactor(reactor)
, m_OnReadable(*this, &MyClientServiceHandler::OnReadable)
, m_OnWritable(*this, &MyClientServiceHandler::OnWritable)
, m_OnTimeout(*this, &MyClientServiceHandler::OnTimeout)
, m_sendBuffer(1024, true)
, m_receiveBuffer(1024, true)
{
    m_socketReactorThread.start(m_reactor);
    
    m_reactor.addEventHandler(m_socket, m_OnReadable);
    m_reactor.addEventHandler(m_socket, m_OnWritable);
    m_reactor.addEventHandler(m_socket, m_OnTimeout);
    
    m_sendBuffer.readable += Poco::delegate(this, &MyClientServiceHandler::OnSend);
        m_receiveBuffer.writable += Poco::delegate(this, &MyClientServiceHandler::OnReceive);
}

~MyClientServiceHandler()
{
    m_reactor.removeEventHandler(m_socket, m_OnReadable);
    m_reactor.removeEventHandler(m_socket, m_OnWritable);
    m_reactor.removeEventHandler(m_socket, m_OnTimeout);
    
    m_sendBuffer.readable -= Poco::delegate(this, &MyClientServiceHandler::OnSend);
    m_receiveBuffer.writable -= Poco::delegate(this, &MyClientServiceHandler::OnReceive);
    
    m_reactor.stop();
    m_socketReactorThread.join();
}
    
void OnReadable(Poco::Net::ReadableNotification* notification)
{
    notification->release();
    
    try {
        int receiveBytes = m_socket.receiveBytes(m_receiveBuffer);
        if (receiveBytes > 0) {
            // здесь делаем важную работу...
        } else {
            delete this;
        }
    } catch (Poco::Exception &e) {
        delete this;
    }
}

void OnWritable(Poco::Net::WritableNotification* notification);

void OnTimeout(Poco::Net::TimeoutNotification* notification)
{
    notification->release();
    m_reactor.stop();
    delete this;
}
    
void OnSend(bool &flag)
{
    if (flag)
        m_reactor.addEventHandler(m_socket, m_OnWritable);
    else
        m_reactor.removeEventHandler(m_socket, m_OnWritable);
}
void OnReceive(bool &flag);

void send(const MyMessage &buffer)
{
        // где вызвать этот метод, если у меня нет экземляра клиента?
    m_sendBuffer.copy(buffer.data(), buffer.size());
}
private:
    Poco::Net::StreamSocket m_socket;
    MySocketReactor &m_reactor;
    Poco::Observer<MyClientServiceHandler, Poco::Net::ReadableNotification> m_OnReadable;
    Poco::Observer<MyClientServiceHandler, Poco::Net::WritableNotification> m_OnWritable;
    Poco::Observer<MyClientServiceHandler, Poco::Net::TimeoutNotification>  m_OnTimeout;

    Poco::Thread m_socketReactorThread;
    
    Poco::FIFOBuffer m_sendBuffer;   // собственно основная замута была ради этого, мне нужны буферы которые оповещают, и хэндлеры
    Poco::FIFOBuffer m_receiveBuffer;
    
    friend std::ostream& operator << (std::ostream&, const MyClientServiceHandler&);
};

class MySocketConnector: public Poco::Net::SocketConnector<MyClientServiceHandler>
{
public:
    MySocketConnector(Poco::Net::SocketAddress& address, MySocketReactor& reactor)
: SocketConnector<MyClientServiceHandler>(address, reactor)
{
    reactor.addEventHandler(socket(), Poco::Observer<MySocketConnector, Poco::Net::TimeoutNotification>(*this, &MySocketConnector::OnTimeout));
    reactor.addEventHandler(socket(), Poco::Observer<MySocketConnector, Poco::Net::ShutdownNotification>(*this, &MySocketConnector::OnShutdown));
}
    void OnShutdown(Poco::Net::ShutdownNotification* notification);
    void OnTimeout(Poco::Net::TimeoutNotification* notification);
    void OnError(int error);

protected:
    MyClientServiceHandler* createServiceHandler() {
    return new MyClientServiceHandler(_socket, *_pReactor);
    }
};

// Используем это дерьмо

class Connection
{
public:
    Connection() : m_connector(m_socketAddress, m_reactor) { ... }
private:
    Poco::Net::SocketAddress m_socketAddress;
    Poco::Net::SocketReactor m_reactor;
    MySocketConnector m_connector; // как это дерьмо использовать? как мне вызвать самый важный метод send(const MyMessage) ?
}


В результате у меня нигде нет доступа к объекту класса MyClientServiceHandler. Как мне положить в исходящий буфер?