我尝试组合Poco::Net::Websocket和Poco::Net::SocketReactor。使用少::净;
class WSConnection: public HTTPRequestHandler{
public:
WSConnection(SocketReactor& reactor):_reactor(reactor){};
void handleRequest(HTTPServerRequest& rqst, HTTPServerResponse& rpns){
this->_ws = new Websocket(rqst, rspns);
this->_reactor.addHandler(this._ws, this._onread_hnd);
this->_reactor.addHandler(this._ws, this._onwrite_hnd);
this->_reactor.addHandler(this._ws, this._onerror_hnd);
}
private:
SocketReactor& _reactor;
};
class WSFactory : public HTTPRequestHandlerFactory{
public:
WSFactory(SocketRactor& reactor): _reactor(reactor){};
void HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
if (!IsWSRequest(request)){
return 0;
}
return new WSConnection(this->_reactor);
}
private:
bool IsWSRequest(const HTTPServerRequest& request){...}
SocketReactor& _reactor;
}
int WSServerApp::main(...){
Poco::Net::SocketReactor r;
Poco::Thread thrd;
WSFactory fctry(r);
Poco::Net::HTTPServer serv(fctry, 35035);
serv.start();
thrd.start(r);
waitForTerminationRequest();
r.stop();
thrd.join();
serv.stop();
}
但是如果我的代码离开handlerrequest(),我调用析构函数WSConnection();还有其他方法来处理一个线程中的连接吗?
我找到解决办法了。需要写两个类:
Server(ServerSocket上的包装器)重写运行方法,部分复制Poco::Net::TCPServer::run()。
Server::Server(const Poco::UInt16 port, const std::string& serv_name):
Runnable(),
SERVER_NAME(serv_name),
_stop(true),
_sock(port),
_clients(),
_thrd(),
_param(new HTTPServerParams())
{
_thrd.setPriority(Poco::Thread::PRIO_HIGH);
_thrd.setName(SERVER_NAME);
_param->setSoftwareVersion(SERVER_NAME);
}
void Server::run(){
while(!_stop.load()){
Poco::Timespan tm(250000);
if (_sock.poll(tm, Socket::SELECT_READ)){
auto ss = _sock.acceptConnection();
ss.setNoDelay(true);
#if defined(POCO_OS_FAMILY_UNIX)
if (ss.address().family() == AddressFamily::UNIX_LOCAL)
{
//ONLY WEBSOCK
throw Poco::IllegalStateException();
}
#endif
auto conn = std::make_shared<Connection>(ss, _param);
_clients.push_back(conn); //std::vector<std::shared_ptr<Websocket>>
}
}
}
和连接与部分复制Poco::Net::HTTPServerConnection::run()
Connection::Connection(StreamSocket& ss, HTTPServerParams::Ptr param):
HTTPServerSession(ss, param),
_ws(), //std::unique_ptr<Websocket>
_rqst(), //std::unique_ptr<HTTPServerRequestImpl>
_rspns() //std::unique_ptr<HTTPServerResponseImpl>
{
_rspns.reset(new HTTPServerResponseImpl(*this));
_rqst.reset(new HTTPServerRequestImpl(*_rspns, *this, param));
//may bee need try and cath with send error state
Init(param);
_ws.reset(new WebSocket(*_rqst, *_rspns));
}
void Connection::Init(const HTTPServerParams::Ptr& param){
_rspns->setDate(Poco::Timestamp());
_rspns->setVersion(_rqst->getVersion());
_rspns->set("Server", param->getSoftwareVersion());
_rspns->setKeepAlive(param->getKeepAlive() && _rqst->getKeepAlive());
}
并添加SocketReactor或Socket::select调用到另一个线程