搜狗的workflow的简单使用

文章介绍了如何使用C++Workflow库创建一个简单的HTTP服务器,并通过wget示例展示其工作原理。同时指出库的过时性,提到了对C++11及以上版本库的期望。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

workflow是一个网络库,是一个基于C++在在线服务引擎
GitHub官网

运行hello world

1,创建一个server,构造函数入参传入一个入参是task的lamda函数,函数的内容会拿到response,并且可以在response中写body
2、server启动,绑定8888端口。这个时候浏览器输入端口可以访问这个服务,并且可以多次访问。3、很显然这个时候进程是在getchar()函数阻塞住了,它在等待用户从键盘输入字符,操作系统中断后将字符给到进程,进程继续执行,server stop

  #include <stdio.h>
  #include "workflow/WFHttpServer.h"

  int main()
  {
      WFHttpServer server([](WFHttpTask *task) {
          task->get_resp()->append_output_body("<html>Hello World!</html>");
      });

      if (server.start(8888) == 0) { // start server on port 8888
          getchar(); // press "Enter" to end.
          server.stop();
      }

      return 0;
  }

在这里插入图片描述

MacBook下如何运行wget:

按照教程运行之后,有以下错误:

(base) ➜  tutorial git:(master) ✗ ./wget
dyld: Library not loaded: libworkflow.0.dylib
  Referenced from: /Users/user/xx/workflow/tutorial/./wget
  Reason: image not found
[1]    62365 abort      ./wget

原因是运行的时候动态链接库路径没有配置,配置一下即可:

export DYLD_LIBRARY_PATH=/Users/xxx/Projects/workflow/_lib:$DYLD_LIBRARY_PATH

wget baidu即可运行成功:

(base) ➜  tutorial git:(master) ✗ ./wget http://www.baidu.com
GET HTTP/1.1 /
Host: www.baidu.com
Accept: */*
User-Agent: Wget/1.14 (linux-gnu)
Connection: close

HTTP/1.1 200 OK
Content-Length: 2381
Content-Type: text/html
Server: bfe
Date: Mon, 19 Feb 2024 17:33:17 GMT
Connection: close

wget源码


#include <netdb.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include "workflow/HttpMessage.h"
#include "workflow/HttpUtil.h"
#include "workflow/WFTaskFactory.h"
#include "workflow/WFFacilities.h"

#define REDIRECT_MAX    5
#define RETRY_MAX       2

void wget_callback(WFHttpTask *task)
{
	protocol::HttpRequest *req = task->get_req();
	protocol::HttpResponse *resp = task->get_resp();
	int state = task->get_state();
	int error = task->get_error();

	switch (state)
	{
	case WFT_STATE_SYS_ERROR:
		fprintf(stderr, "system error: %s\n", strerror(error));
		break;
	case WFT_STATE_DNS_ERROR:
		fprintf(stderr, "DNS error: %s\n", gai_strerror(error));
		break;
	case WFT_STATE_SSL_ERROR:
		fprintf(stderr, "SSL error: %d\n", error);
		break;
	case WFT_STATE_TASK_ERROR:
		fprintf(stderr, "Task error: %d\n", error);
		break;
	case WFT_STATE_SUCCESS:
		break;
	}

	if (state != WFT_STATE_SUCCESS)
	{
		fprintf(stderr, "Failed. Press Ctrl-C to exit.\n");
		return;
	}

	std::string name;
	std::string value;

	/* Print request. */
	fprintf(stderr, "%s %s %s\r\n", req->get_method(),
									req->get_http_version(),
									req->get_request_uri());

	protocol::HttpHeaderCursor req_cursor(req);

	while (req_cursor.next(name, value))
		fprintf(stderr, "%s: %s\r\n", name.c_str(), value.c_str());
	fprintf(stderr, "\r\n");

	/* Print response header. */
	fprintf(stderr, "%s %s %s\r\n", resp->get_http_version(),
									resp->get_status_code(),
									resp->get_reason_phrase());

	protocol::HttpHeaderCursor resp_cursor(resp);

	while (resp_cursor.next(name, value))
		fprintf(stderr, "%s: %s\r\n", name.c_str(), value.c_str());
	fprintf(stderr, "\r\n");

	/* Print response body. */
	const void *body;
	size_t body_len;

	resp->get_parsed_body(&body, &body_len);
	fwrite(body, 1, body_len, stdout);
	fflush(stdout);

	fprintf(stderr, "\nSuccess. Press Ctrl-C to exit.\n");
}

static WFFacilities::WaitGroup wait_group(1);

void sig_handler(int signo)
{
	wait_group.done();
}

int main(int argc, char *argv[])
{
	WFHttpTask *task;

	if (argc != 2)
	{
		fprintf(stderr, "USAGE: %s <http URL>\n", argv[0]);
		exit(1);
	}

	signal(SIGINT, sig_handler);

	std::string url = argv[1];
	if (strncasecmp(argv[1], "http://", 7) != 0 &&
		strncasecmp(argv[1], "https://", 8) != 0)
	{
		url = "http://" + url;
	}

	task = WFTaskFactory::create_http_task(url, REDIRECT_MAX, RETRY_MAX,
										   wget_callback);
	protocol::HttpRequest *req = task->get_req();
	req->add_header_pair("Accept", "*/*");
	req->add_header_pair("User-Agent", "Wget/1.14 (linux-gnu)");
	req->add_header_pair("Connection", "close");
	task->start();

	wait_group.wait();
	return 0;
}

1、waitgroup.done,在后面等待http结束
2、解析并处理输入的url
3、创造task,入参是url、最大重定向数、最大retry数量、入参是task的callback
4、task请求url
5、callback函数开始真正执行:http请求-》拿到response、state-》通过cursor来遍历req、response
-》从response中拿到body-》通过fwrite写到stdout-》fflush(stdout)

缺点

感觉这个库太古老,还用到了fwrite、fflush这种需要记忆的知识,现在这个时代为啥不用C++11之后的库呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值