mongoose c++封装
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongoose c++封装相关的知识,希望对你有一定的参考价值。
mongoose c++封装
封装以后暴露一个回调函数,让main函数调用即可
#pragma once
#include "mongoose.h"
//#include "../CorePhone/TThreadRunable.h"
typedef void(*websocket_callback)(int flag, const char *p);
static websocket_callback g_callback = NULL;
class Service_HTTP //:public TThreadRunable
{
public:
char *s_http_port = "8000";
struct mg_serve_http_opts s_http_server_opts;
struct mg_mgr mgr;
struct mg_connection * _nc = NULL;
//websocket_callback _callback = NULL;
public:
void setcallback(websocket_callback callback)
{
g_callback = callback;
}
static int is_websocket(const struct mg_connection *nc) {
return nc->flags & MG_F_IS_WEBSOCKET;
}
static void broadcast(struct mg_connection *nc, const struct mg_str msg) {
char buf[16];
char bufname[128];
const char * pmsg = msg.p;
int len = msg.len;
int namelen = 0;
int flag = -1;
if (len > 7)
{
memcpy(buf, pmsg, 6);
buf[6] = '\\0';
if (strcmp(buf, "RECORD") == 0)
flag = 1;
else if (strcmp(buf, "FINISH") == 0)
flag = 2;
else
flag = 3;
}
if (msg.len > 8)
{
char c = *(pmsg + 6);
if (c == ':')
{
namelen = len - 7;
memcpy(bufname, pmsg + 7, namelen);
bufname[len - 7] = '\\0';
}
}
//memcpy(buf, msg.p, msg.len);
//buf[msg.len] = '\\0';
struct mg_connection *c;
//以下是广播信息
//snprintf(buf, sizeof(buf), "%s %.*s", (int)msg.len, msg.p);
//printf("%s\\n", buf); /* Local echo. */
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
//if (c == nc) continue; /* Don't send to the sender. */
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf));
}
if (namelen != 0)
{
if (g_callback != NULL)
g_callback(flag, &bufname[0]);
}
}
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
switch (ev) {
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
/* New websocket connection. Tell everybody. */
//broadcast(nc, mg_mk_str("++ joined"));
break;
}
case MG_EV_WEBSOCKET_FRAME: {
struct websocket_message *wm = (struct websocket_message *) ev_data;
/* New websocket message. Tell everybody. */
struct mg_str d = { (char *)wm->data, wm->size };
broadcast(nc, d);
break;
}
case MG_EV_HTTP_REQUEST: {
Service_HTTP *service = (Service_HTTP *)nc->user_data;
mg_serve_http(nc, (struct http_message *) ev_data, service->s_http_server_opts);
break;
}
case MG_EV_CLOSE: {
/* Disconnect. Tell everybody. */
if (is_websocket(nc)) {
//broadcast(nc, mg_mk_str("-- left"));
}
break;
}
}
}
//广播该视频数据
void WebSocket_Broadcast(uint8_t * data, int len)
{
struct mg_connection *c;
if (_nc != NULL) {
for (c = mg_next(_nc->mgr, NULL); c != NULL; c = mg_next(_nc->mgr, c)) {
if (c == _nc) continue; /* Don't send to the sender. */
mg_send_websocket_frame(c, WEBSOCKET_OP_BINARY, data, len);
}
}
}
public:
void Stop()
{
_stop = 1;
//TThreadRunable::Stop();
//Join();
}
void Run()
{
mg_mgr_init(&mgr, NULL);
_nc = mg_bind(&mgr, s_http_port, ev_handler);
_nc->user_data = this;
mg_set_protocol_http_websocket(_nc);
s_http_server_opts.document_root = "./public"; // Serve current directory
s_http_server_opts.enable_directory_listing = "yes";
//printf("Started on port %s\\n", s_http_port);
while (!_stop) {
mg_mgr_poll(&mgr, 200);
}
mg_mgr_free(&mgr);
}
private:
int _stop = 0;
};
使用
其中读配置文件等等就不贴出代码了,这个我们把配置写进代码就行,可以去掉,Mp4WrapperNet.h这个也可以去掉,关注回调函数就好
#include <stdio.h>
#include "Mp4WrapperNet.h"
#include "time.h"
#include <signal.h>
#include <chrono>
#include <thread>
#include "service_http.h"
#include <string>
#include <iostream>
#include "rrconfig.h"
using namespace std;
//int gStopProcess = 0;
//Mp4Wrapper g_wrapper;
Service_HTTP HTTPServer;
static string g_IP;
static string gettime_now()
{
char buff[64];
//char buff2[256];
time_t t = time(NULL);
strftime(buff, sizeof(buff), "%Y_%m_%d_%H_%M_%S", localtime(&t));
//printf("%s\\n", buff);
return buff;
}
static void callback(int flag, const char * name)
{
switch (flag)
{
case 1:
{
if (g_IP.empty() || g_IP == "" )
{
cout << "IP address is empty!" << endl;
g_IP = "127.0.0.1";
}
string str = "rtmp://" + g_IP + "/live/" + name;
string file = "./public/";
file += name;
file += gettime_now();
file += ".mp4";
g_wrapper.Add(name, str.c_str(), file.c_str());
g_wrapper.Start(name);
cout <<"start:"<< str <<":"<<file<< endl;
}
break;
case 2:
{
g_wrapper.Stop(name);
cout << "stop:" << name << endl;
}
break;
case 3:
{
cout << "error command" << endl;
}
break;
case 4://设定IP地址
g_IP = name;
break;
}
}
void exithandle(int n)
{
HTTPServer.Stop();
}
int main(int argc, char *argv[])
{
rr::RrConfig config;
if (config.ReadConfig("config.ini"))
{
g_IP = config.ReadString("server", "ip", "");
}
//Mp4Wrapper::Init();
std::cout << "http server and websocket at port:8000 " << endl;
//g_wrapper.Add("abc", "rtmp://127.0.0.1/live/qianbo123", "d:\\\\a.mp4");
signal(SIGINT, exithandle);
//g_wrapper.Start("abc");
HTTPServer.setcallback(callback);
HTTPServer.Run();
//Mp4Wrapper::UnInit();
//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0;
}
以上是关于mongoose c++封装的主要内容,如果未能解决你的问题,请参考以下文章
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段
VSCode自定义代码片段14——Vue的axios网络请求封装
VSCode自定义代码片段14——Vue的axios网络请求封装