tôi muốn khuyên bạn sử dụng Boost's ASIO thư viện
Bạn sẽ cần một lớp học để chấp nhận các yêu cầu mới và một để kiểm tra định kỳ để cập nhật. Cả hai có thể làm công việc của họ một cách không đồng bộ và sử dụng cùng một boost :: asio :: io_service để lên lịch công việc.
Quá trình cài đặt sẽ
- Một không đồng bộ mạng
boost::asio::ip::tcp::acceptor
nghe cho các yêu cầu mới.
- A
boost::asio::deadline_time
làm một sự chờ đợi không đồng bộ để kiểm tra các bản cập nhật cho cơ sở dữ liệu.
Pseudo mã cho những gì tôi hiểu bạn đang mô tả là dưới đây:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
class DatabaseUpdateChecker{
public:
DatabaseUpdateChecker(boost::asio::io_service& io, const int& sleepTimeSeconds)
:timer_(io,boost::posix_time::seconds(sleepTimeSeconds)),sleepSeconds_(sleepTimeSeconds){
this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error));
};
protected:
void doDBUpdateCheck(const boost::system::error_code& error){
if(!error){
std::cout << " Checking Database for updates" << std::endl;
//Reschdule ourself
this->timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(this->sleepSeconds_));
this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error));
}
};
private:
boost::asio::deadline_timer timer_;
int sleepSeconds_;
};
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> TcpSocketPtr;
class NetworkRequest{
public:
NetworkRequest(boost::asio::io_service& io, const int& port)
:acceptor_(io,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port)){
this->start_accept();
};
protected:
void start_accept(){
TcpSocketPtr socketPtr(new boost::asio::ip::tcp::socket(acceptor_.get_io_service()));
std::cout << "About to accept new connection" << std::endl;
acceptor_.async_accept(*socketPtr,boost::bind(&NetworkRequest::handle_accept,this,socketPtr,boost::asio::placeholders::error));
};
void handle_accept(TcpSocketPtr socketPtr,const boost::system::error_code& error){
std::cout << "Accepted new network connection" << std::endl;
if(!error){
std::string response("This is a response\n");
boost::asio::async_write(*socketPtr,boost::asio::buffer(response),
boost::bind(&NetworkRequest::handle_write,this,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
//Start listeing for a new connection
this->start_accept();
}
void handle_write(const boost::system::error_code& error,size_t size){
if(!error){
std::cout << "Wrote out " << size << " bytes to the network connection" << std::endl;
}
}
private:
boost::asio::ip::tcp::acceptor acceptor_;
};
int main(int argc, char *argv[]) {
static const int DB_TIMER_SECONDS=5;
static const int LISTENING_TCP_PORT=4444;
std::cout << "About to start" << std::endl;
boost::asio::io_service io;
DatabaseUpdateChecker dbChecker(io,DB_TIMER_SECONDS);
NetworkRequest networkRequestAcceptor(io,LISTENING_TCP_PORT);
io.run();
std::cout << "This won't be printed" << std::endl;
return 0;
}
Biên dịch ở trên và chạy nó sẽ cho thấy rằng cơ sở dữ liệu Update Checker sẽ kiểm tra cập nhật mỗi 5 giây khi nghe cho các kết nối trên Cổng TCP 4444. Để xem mã chấp nhận kết nối mới, bạn có thể sử dụng công cụ mạng khách/mạng yêu thích của telnet/netcat ....
telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
This is a response
Connection closed by foreign host.
Nếu bạn thấy rằng việc xử lý cập nhật và/hoặc yêu cầu mất một khoảng thời gian đáng kể thì tôi sẽ xem từng công việc trong chuỗi của riêng nó. io_service sẽ lên kế hoạch công việc cần làm và không hoàn thành cho đến khi không còn hoạt động nữa. Bí quyết là để các lớp học làm công việc lên lịch lại khi chúng được thực hiện.
Tất nhiên bạn phải tính đến nhận xét của người khác về câu hỏi của bạn. Tôi không biết làm thế nào một giao diện CORBA có thể phức tạp này nhưng tôi sẽ nghĩ rằng tăng :: asio như một thư viện C++ không đồng bộ sẽ là một quyết định tốt và đủ linh hoạt cho những gì bạn mô tả.
Làm thế nào về một chương trình đa luồng? –
Bạn đã xem Boost ASIO chưa? Có IO đồng bộ và không đồng bộ, bộ hẹn giờ và hơn thế nữa. http://www.boost.org/doc/libs/release/libs/asio/ – Joel
Để sử dụng cách tiếp cận theo luồng. Tôi có thể thiết lập thread đó thành daemon như cách nó được thực hiện trong python không? Bởi vì phần còn lại của chương trình thực sự không cần các chủ đề như của nó trên CORBA. @Jelel đến ASIO, hãy khai sáng cho tôi. Nó trông giống như một lựa chọn tốt (tôi có rất ít kiến thức về asio) nhưng có vẻ như một cuộc gọi chặn đến io_service.run(). Tôi muốn chạy không đồng bộ chức năng cho các truy vấn dbqueries định kỳ bất kể máy chủ làm gì. Họ là khá nhiều tách ra, ngoại trừ họ sẽ chia sẻ một biến. Trong khi máy chủ tiếp tục chạy, hàm kia phải chạy không đồng bộ. – King