由于我这里本身是做服务端然后需要发送定时发送消息到企业微信,所以其实我这里服务端也会有https请求到企业微信
一、定时发送
这里我使用poco的定时器Timer,新建一个,TimerMessagePush 的类,指定CheckPush这个方法为定时启动的任务。启动定时器就能正常工作了。启动之后间隔2000ms触发一次,每一天触发一次。
TimerMessagePush就是一个普通的类,CheckPush也只是一个普通的方法
int HTTPSServer::main(const std::vector<std::string>& args)
{
unsigned short port = (unsigned short)config().getInt("HTTPTimeServer.port", 9980);
std::string format(config().getString("HTTPTimeServer.format", DateTimeFormat::SORTABLE_FORMAT));
int maxQueued = config().getInt("HTTPTimeServer.maxQueued", 100);
int maxThreads = config().getInt("HTTPTimeServer.maxThreads", 16);
ThreadPool::defaultPool().addCapacity(maxThreads);
HTTPServerParams* pParams = new HTTPServerParams;
pParams->setMaxQueued(maxQueued);
pParams->setMaxThreads(maxThreads);
// set-up a server socket
ServerSocket svs(port);
// set-up a HTTPServer instance
HTTPServer srv(new TimeRequestHandlerFactory(format), svs, pParams);
// start the HTTPServer
//检查专利过期对象
TimerMessagePush te(format);
Timer timer(2000, 86400000); // 2000后启动,每一天重复一次
timer.start(TimerCallback<TimerMessagePush>(te, &TimerMessagePush::CheckPush));
srv.start();
// wait for CTRL-C or kill
waitForTerminationRequest();
// Stop the HTTPServer
timer.stop();
srv.stop();
//}
return Application::EXIT_OK;
}
二、https请求
1.这里以获取企业微信的totken的例子
1.1pContext的构建
pContext这里构建的时有两个版本,一个 是NetSSL_Win里面的就如下面的,参数少了两个参数。还有一个是NetSSL_OpenSSL这个的Context初始化函数会多两个,windwos其实无所谓,就是NetSSL_OpenSSL这个需要对应的dll和头文件.编译的时候还是会需要下载openssl的环境的。下面这个是NetSSL_OpenSSL的构建
Context::Ptr ptrContext = new Context(Context::TLS_CLIENT_USE, "", "", "rootcert.pem", Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
2.2 创建https请求
如下指定请求方式HTTP_POST,strURL这个企业微信这里必须把所有的内容传上去,指定http版本。这个其实和http一样,https只是多了Context 这个。
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, strUrl, Poco::Net::HTTPMessage::HTTP_1_1);
bool TimerMessagePush::GetToken(std::string& strToken)
{
std::string strResponse;//获取token收到的字符
try {
std::string strUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=ftClef11KdvlIFR_g";
const Context::Ptr pContext = new Context(Context::CLIENT_USE, "", Context::VERIFY_NONE, 9, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(0, 0, pContext);
URI uri(strUrl);
// 创建 HTTPS 客户端会话
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
// 创建 HTTP 请求
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, strUrl, Poco::Net::HTTPMessage::HTTP_1_1);
// 发送请求
session.sendRequest(request);
// 接收响应
Poco::Net::HTTPResponse response;
std::istream& rs = session.receiveResponse(response);
// 输出响应状态
if (200 != response.getStatus())
{
std::cout << "Response status :" << response.getStatus() << "Reason: " << response.getReason() << std::endl;
strToken = "";
return false;
}
// 读取响应内容
std::ostringstream responseStream;
Poco::StreamCopier::copyStream(rs, responseStream);
strResponse = responseStream.str();
std::cout << "Response body: " << responseStream.str() << std::endl;
}
catch (const Poco::Exception& ex) {
strToken = "";
std::cerr << "Poco Exception: " << ex.displayText() << std::endl;
}
catch (const std::exception& ex) {
strToken = "";
std::cerr << "Standard Exception: " << ex.what() << std::endl;
}
//解析返回内容
try
{
//strResponse="{\"errcode\":0,\"errmsg\":\"ok\",\"access_token\":\"Token...\",\"expires_in\":7200}";
if (strResponse.empty())
{
strToken = "";
return false;
}
//创建解析器
Parser sparser;
// 解析 JSON 字符串
sparser.parse(strResponse);
//获取结果
Poco::DynamicAny json = sparser.result();
//Serialize to string
Poco::JSON::Object::Ptr obj;
if (json.type() != typeid(Poco::JSON::Object::Ptr))
return false;
obj = json.extract<Poco::JSON::Object::Ptr>();
Var vErrcode = obj->get("errcode");
int nErrcode = 0;
if (vErrcode.isInteger() || vErrcode.isNumeric())
{
nErrcode = vErrcode;
}
if (0 != nErrcode)
{
strToken = "";
return false;
}
Var vErrmsg = obj->get("errmsg");
std::string strErrmsg="";
if (vErrmsg.type() == typeid(std::string))
{
strErrmsg = vErrmsg.toString();
}
if ("ok" != strErrmsg)
{
std::cout << strErrmsg << std::endl;
strToken = "";
return false;
}
Var vAccessToken = obj->get("access_token");
if (vErrmsg.type() == typeid(std::string))
{
strToken = vAccessToken.toString();
return true;
}
else
{
strToken = "";
return false;
}
}
catch (Poco::JSON::JSONException& jsone)
{
std::cout << jsone.message() << std::endl;
}
return false;
}