先学习一下源码:GitHub - cesanta/mongoose at 7.2
mqtt使用秘钥和密码链接参考:
tls_set("../mqttTest/testdir/cfgdir/ca/ca.crt", "../mqttTest/testdir/cfgdir/ca/",
"../mqttTest/testdir/cfgdir/client/client.crt", "../mqttTest/testdir/cfgdir/client/client.key",
NULL);
tls_opts_set(0, NULL, NULL);
username_pw_set("surp", "123");
#include <mosquittopp.h>
class testMqtt : public mosqpp::mosquittopp
{
public:
testMqtt(const char *id, const char *host, int port): mosquittopp(id)
{
int keepalive = 60;
//使用RSA,登录方式连接参考
tls_set("../mqttTest/testdir/cfgdir/ca/ca.crt", "../mqttTest/testdir/cfgdir/ca/",
"../mqttTest/testdir/cfgdir/client/client.crt", "../mqttTest/testdir/cfgdir/client/client.key",
NULL);
tls_opts_set(0, NULL, NULL);
username_pw_set("surp", "123");
connect(host, port, keepalive);
}
~testMqtt()
{
}
void on_connect(int rc)
{
printf("Connected with code %d.\n", rc);
if(rc == 0){
/* Only attempt to subscribe on a successful connect. */
subscribe(NULL, "echo_on");
}
}
void on_message(const struct mosquitto_message *message)
{
double temp_celsius, temp_fahrenheit;
char buf[51];
if(!strcmp(message->topic, "echo_on")){
logwdbg("%s", (char *)message->payload);
memset(buf, 0, 51*sizeof(char));
/* Copy N-1 bytes to ensure always 0 terminated. */
memcpy(buf, message->payload, 50*sizeof(char));
temp_celsius = atof(buf);
temp_fahrenheit = temp_celsius*9.0/5.0 + 32.0;
snprintf(buf, 50, "%f", temp_fahrenheit);
publish(NULL, "temperature/fahrenheit", strlen(buf), buf);
}
}
void on_subscribe(int mid, int qos_count, const int *granted_qos)
{
printf("Subscription succeeded.\n");
}
};
int main(int argc,char *argv[])
{
testMqtt *tempconv;
int rc;
logwdbg("");
mosqpp::lib_init();
logwdbg("");
tempconv = new testMqtt("tempconv", "192.168.6.48", 23333);
logwdbg("");
tempconv->loop_forever();
logwdbg("");
mosqpp::lib_cleanup();
return 0;
}
通过mongoose获取时间:http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp
#include <types.h>
#include <ctimer.h>
#include <json/json.h>
#include <base64Java.h>
#include <zlib.h>
#include <logBaseWork.h>
#include <hexbufToStr.h>
#include <mosquittopp.h>
#include <baseProt.h>
#include <miscOperate.h>
#include <openssl/md5.h>
#include <sqlTabOptCom.h>
#include <mongoose.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define DEST_PORT 80
#define DEST_IP_BY_NAME "http://api.m.taobao.com"
typedef void (*reqfn)(struct mg_connection *c, int ev, void *ev_data, void *fn_data);
struct HttpReqBaseInfo
{
int runflag;
std::string urls;
reqfn cfn;
void *data;
};
int httpReqRun(struct HttpReqBaseInfo *reqinf)
{
if (!(reqinf && reqinf->urls != "" && reqinf->cfn != nullptr))
{
// logwerr("");
return -1;
}
logwdbg("%s", reqinf->urls.c_str());
struct mg_mgr mgr;
timerc tmpTimeOut = timerc();
reqinf->runflag = 0;
mg_log_set("1");
mg_mgr_init(&mgr);
mg_http_connect(&mgr, reqinf->urls.c_str(), reqinf->cfn, reqinf);
while (!reqinf->runflag)
{
mg_mgr_poll(&mgr, 300);
if (tmpTimeOut.intms() > 1000)
{
break;
}
}
mg_mgr_free(&mgr);
logwwrn("%d", reqinf->runflag);
if (reqinf->runflag != 1)
{
return -2;
}
return 0;
}
void reqWebTimeCallback(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
struct HttpReqBaseInfo *tmpinf = (struct HttpReqBaseInfo *)fn_data;
if (ev == MG_EV_CONNECT)
{
struct mg_str host = mg_url_host(tmpinf->urls.c_str());
// logwdbg("");
mg_printf(c,
"GET %s/rest/api3.do?api=mtop.common.getTimestamp HTTP/1.1\r\n"
"Host: %.*s\r\n"
"\r\n",
tmpinf->urls.c_str(), (int)host.len, host.ptr);
}
else if (ev == MG_EV_HTTP_MSG)
{
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
logwdbg("%s", hm->body.ptr);
Json::Value tmpvals;
Json::Reader tmpjr;
tmpjr.parse(hm->body.ptr, tmpvals);
Json::Value tmpdata = tmpvals["data"];
std::string tmpstr = jsoncppComOptClass::getJsonStr(tmpdata, "t", "");
logwdbg("%s", tmpstr.c_str());
time_t tnows = atoll(tmpstr.c_str());
tnows /= 1000;
struct tm *tmnow = localtime(&tnows);
logwdbg("%d-%d-%d %d:%d:%d", tmnow->tm_year + 1900, tmnow->tm_mon + 1,
tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
// logwdbg("%s", tmpAesDec.c_str());
c->is_closing = 1; // Tell mongoose to close this connection
tmpinf->runflag = 1;
}
else if (ev == MG_EV_ERROR)
{
c->is_closing = 1; // Tell mongoose to close this connection
logwdbg("");
tmpinf->runflag = -1;
}
}
int main(int argc,char *argv[])
{
struct HttpReqBaseInfo tmpreqinf = {0, DEST_IP_BY_NAME, reqWebTimeCallback, &tmpreqinf};
httpReqRun(&tmpreqinf);
return 0;
}
对于mongoose7.9,
如果要用postman调试,以及传输文件,可以参考:
https://github.com/cesanta/mongoose/blob/7.9/examples/file-upload-html-form/main.c
如果用https参考:
MG_ENABLE_SSI=1
MG_ENABLE_OPENSSL=1
https://github.com/cesanta/mongoose/tree/7.9/examples/http-restful-server
如果直接用http1.1厚块,也可以参考
https://github.com/cesanta/mongoose/tree/7.9/examples/http-restful-server
mg_http_write_chunk写入厚块后,http->body就是我们的数据了。
#include "mongoose.h"
static const char *s_http_addr = "http://192.168.6.48:8000"; // HTTP port
static const char *s_https_addr = "https://192.168.6.48:8443"; // HTTPS port
static const char *s_root_dir = ".";
// We use the same event handler function for HTTP and HTTPS connections
// fn_data is NULL for plain HTTP, and non-NULL for HTTPS
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
if (ev == MG_EV_ACCEPT && fn_data != NULL)
{
struct mg_tls_opts opts = {
//.ca = "ca.pem", // Uncomment to enable two-way SSL
.cert = "server.pem", // Certificate PEM file
.certkey = "server.pem", // This pem contains both cert and key
};
mg_tls_init(c, &opts);
}
else if (ev == MG_EV_HTTP_MSG)
{
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
if (mg_http_match_uri(hm, "/api/stats"))
{
// Print some statistics about currently established connections
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next)
{
mg_http_printf_chunk(c, "%-3lu %4s %s %I %I\n", t->id,
t->is_udp ? "UDP" : "TCP",
t->is_listening ? "LISTENING"
: t->is_accepted ? "ACCEPTED "
: "CONNECTED",
4, &t->loc.ip, 4, &t->rem.ip);
}
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
}
else if (mg_http_match_uri(hm, "/api/f2/*"))
{
// mg_http_reply(c, 200, "", "{\"result\": \"%.*s\"}\n", (int)hm->uri.len,
// hm->uri.ptr);
struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
mg_http_serve_file(c, hm, "server.pem", &opts);
}
else if (mg_http_match_uri(hm, "/api/bigdata"))
{
std::string tmpstr;
tmpstr.resize(2 * 1024 * 1024);
for(int i = 0; i < tmpstr.size(); i++)tmpstr[i] = '1';
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
mg_http_write_chunk(c, tmpstr.c_str(), tmpstr.length());
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
}
else
{
struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
mg_http_serve_dir(c, hm, &opts);
}
}
(void)fn_data;
}
int main(void)
{
struct mg_mgr mgr; // Event manager
mg_log_set(MG_LL_DEBUG); // Set log level
mg_mgr_init(&mgr); // Initialise event manager
mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener
mg_http_listen(&mgr, s_https_addr, fn, (void *)1); // HTTPS listener
for (;;)
mg_mgr_poll(&mgr, 1000); // Infinite event loop
mg_mgr_free(&mgr);
return 0;
}