2021-6-6 今天改成了c++ 20 协程
具体修改:改成c++ 20 协程 删除boost库

c++ 2019协程

在vs2019 里面 加上/await
vs2019 里加上命令

gcc10 版本

gcc10 版本以上 需要fcoroution 支持
代码已经上传

c++ 20 协程方式 websocket server
websocket server

增加websocket html 测试 [2021-6-6]

在代码目录下 testwebsocket.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket 测试</title>

    <script type="text/javascript">
         function WebSocketTest()
         {
            if ("WebSocket" in window)
            {
               console.log("!");

               // 打开一个 web socket
               var ws = new WebSocket("ws://127.0.0.1:6001/echo");

               ws.onopen = function()
               {
                  // Web Socket 已连接上,使用 send() 方法发送数据
                  ws.send("data here");
               };

               ws.onmessage = function (evt)
               {
                   var received_msg = evt.data;
                   console.log(received_msg);
               };

               ws.onclose = function()
               {
                  // 关闭 websocket
                  alert("连接已关闭...");
               };
            }

            else
            {
               console.log("不支持 WebSocket!");
            }
         }
    </script>

</head>
<body>

    <div id="sse">
        <a href="javascript:WebSocketTest()">运行 WebSocket</a>
    </div>

</body>
</html>

目的

从web上传图片和视频,httpserver后台接收,进行图片识别并返回
使用框架
1 asio
2 websocketpp
3 websock 【紫丁香研发】
4 opencv
5 调用python

httpserver和websocket server

第一版使用的httpserver 和 websocket server 是由websocketpp制作的

路由

比如nodejs 的 express 或 koi
比如go 语言的iris 等等那种路由方式很理想
这里模仿这种方式,使用c++11 的lamba

void registerhttp()
{
	broadcast_server& _httpserver = _hserver;
	_httpserver.func_proc_register("/login", [](maps_pair& rp) {
		
		auto iter = rp.begin();
		while (iter != rp.end())
		{
			std::cout << iter->first << " " << iter->second << std::endl;
		}
		return;
	});

	_httpserver.func_proc_register("/url", [](maps_pair& rp) {
		cout << "url get" << endl;
		return;
	});

}

int main(int argc, char** argv)
{
	registerhttp();
	_hserver.Start(80);
	_hserver.Join();
	return 0;
}

实现

bool func_proc_register(std::string uri, handler_2http f) {

		auto it = v_map_function.find(uri);
		if (v_map_function.end() != it)
			return false;
		route_request rr;
		rr.func = f;
		return v_map_function.emplace(uri, rr).second;
	}

实际上,在类内部插入了一个回调函数vmap,在用户浏览上输入后,后台从url地址中获取所有参数,并进行比对。

void on_http(websocketpp::connection_hdl hdl)
	{
		try
		{
			c_server::connection_ptr con = m_server.get_con_from_hdl(hdl);
			websocketpp::http::parser::request rt = con->get_request();

			const string& strUri = rt.get_uri();
			const string& strMethod = rt.get_method();
			const string& strBody = rt.get_body();	//只针对post时有数据
			const string& strHost = rt.get_header("host");
			const string& strVersion = rt.get_version();
			//std::cout << "接收到一个" << strMethod.c_str() << "请求:" << strUri.c_str() << "  线程ID=" << ::GetCurrentThreadId() << "  host = " << strHost << std::endl;
			if (strMethod.compare("POST") == 0)
			{//对于post提交的,直接返回跳转
				con->set_status(websocketpp::http::status_code::value(websocketpp::http::status_code::found));
				con->append_header("location", "http://localhost");
			}
			else if (strMethod.compare("GET") == 0)
			{
				if (strUri.compare("/") == 0)
				{//请求主页
					con->set_body("Hello We Meeting Here! Please use more route");
					con->set_status(websocketpp::http::status_code::value(websocketpp::http::status_code::ok));
				}
				else if (strUri.compare("/favicon.ico") == 0)
				{//请求网站图标,读取图标文件,直接返回二进制数据

					con->set_body("");
					//con->append_header("Content-Type", "image/x-icon");
					con->set_status(websocketpp::http::status_code::value(websocketpp::http::status_code::ok));
				}
				else if (strUri.compare("/test1") == 0)
				{
					con->set_body("test1 come here");
					con->set_status(websocketpp::http::status_code::value(
						websocketpp::http::status_code::ok));
				}
				else
				{//其他未定义的页面,返回跳转
					cout <<"uri:"<<strUri << endl;
					con->append_header("Access-Control-Allow-Origin", "*");
					con->append_header("Access-Control-Allow-Methods", "GET,POST");
					con->append_header("Access-Control-Allow-Headers", "x-requested-with,content-type");
					std::map<string, string> list;	//操作参数列表	
					string url;//路由参数
					GetReqeustAndParmeter(strUri, url, list);
					cout << "url is:" << url << endl;
					auto iter = v_map_function.find(url);
					if (iter == v_map_function.end())
					{
						string reply = "{\"ret\":-1,\"info\":\"no this parameter\"}";
						con->set_body(reply.c_str());
						con->set_status(websocketpp::http::status_code::value(websocketpp::http::status_code::ok));
						return;
					}
					else {
						route_request& rr = iter->second;
						if (rr.func != nullptr)
						{
							rr.func(list);
						}
						con->set_body(rr.retString.c_str());
						//con->set_body("{\"ret\":0}");
						con->set_status(websocketpp::http::status_code::value(websocketpp::http::status_code::ok));
					}
				}
			}
		}
		catch (websocketpp::exception const& e)
		{
			std::cout << "exception: " << e.what() << std::endl;
		}
		catch (std::exception& e)
		{
			std::cout << "exception: " << e.what() << std::endl;
		}
		catch (...)
		{

		}
	}	

适用系统

1 windows
vs2019
2 linux
编译cmake

全部代码:

紫丁香地址
在gitee 上。每个星期更新

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐