html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Добавляем Web API для программы на C++ с помощью библиотеки POCO tutorial

В жизни любой достаточно большой программы наступает момент, когда нужно вывести наружу какой-нибудь API — для плагинов, для интеграции с другими системами, для автоматизации и т.д. Для этого есть много разных технологий, но как-то так исторически сложилось, что сейчас принято делать API в виде REST-сервисов. В принципе, если не гнаться за экономией каждого байта и микросекунды, то в этом есть смысл: HTTP-запрос сделать легко из любого языка, это хорошо работает и локально, и по сети, не нужно сильно глубоко погружаться в недры сетевых протоколов.
Давайте посмотрим, как к уже существующей программе на C++ можно быстренько прикрутить Web API, используя для этого библиотеку POCO.

Задача


Пусть у нас есть вот такая программа:
#include <iostream>
#include <conio.h>

int main(int argc, char** argv)
{
	for(;;)
	{
		std::cout << "Hello world!" << std::endl;
		_getch();
	}

	return 0;
}


Мы хотим дать возможность извне менять выводимый текст. Для этого клиенту будет достаточно сделать запрос вида:
http://host:port/setText?text=NewText


Собираем POCO


  1. Идём вот сюда и скачиваем последнюю версию Basic Edition for Windows (1.4.6p1 на момент написания этой статьи).
  2. Разархивируем куда-нибудь.
  3. Идём туда, куда разархивировали и видим там батники с именами build_vs90.cmd, build_vs100.cmd, build_vs110.cmd. Они собирают библиотеку POCO с помощью разных версий Visual Studio. Просто запустите нужный (студия, само-собой, к этому моменту должна быть уже установлена). Я лично компилировал POCO под VS2008, VS2010 и VS2012 — проблем не возникло ни разу.


Подключаем POCO к своему проекту


  1. Сделайте в папке своего проекта папку POCO
  2. В этой папке сделайте три подпапки: include, lib, bin.
  3. В папку include скопируйте все заголовочные файлы POCO (из папок %POCO%\XML\include, %POCO%\Util\include, %POCO%\Net\include и %POCO%\Foundation\include)
  4. В папку lib скопируйте lib-файлы из %POCO%\lib. Для удобства можно разнести их по подпапкам Debug и Release.
  5. В папку bin скопируйте dll-файлы из %POCO%\bin. Их аналогично можно разнести по подпапкам Debug и Release.
  6. Добавьте путь к папке include в Additional Include Directories, а путь к папке lib — в Additional Library Directories своего проекта. Удобно использовать переменную $(SolutionDir) и относительные пути.
  7. Добавьте файлы PocoFoundationd.lib, PocoNetd.lib, PocoUtild.lib в Additional Dependencies проекта для Debug-конфигурации, а их версии без буквы «d» в конце — для Release-конфигурации.
  8. Не забудьте, что dll-файлы из папки bin нужно будет деплоить вместе с вашим приложением. Можете просто их скопировать в папки Debug\Release или сделать шаг в процессе компиляции, где они будут туда копироваться.

В конце топика есть ссылка на настроенный проект на GitHub — можете использовать его как базу.

Используем POCO для создания Web API


Код получается очень простой и понятный. В главном файле создаём объект класса, унаследованного от ServerApplication. Это позволит нам сохранить в главном потоке вывод наших сообщений, одновременно запустив в другом потоке веб-сервер с помощью класса HTTPServer. Для того, чтобы объяснить веб-серверу, как обрабатывать входящие запросы мы сделаем свою фабрику, унаследованную от HTTPRequestHandlerFactory. На каждый запрос она будет создавать новый объект обработчика (класса, унаследованного от HTTPRequestHandler), который уже и будет заниматься разбором входящего запроса, его обработкой и выдачей клиенту результата.

В коде всё выглядит даже проще, чем в описании выше.

PocoHelloWorld.cpp
#include "MyRequestHandler.h"

int main(int argc, char** argv)
{
	MyServerApp app;
	return app.run(argc, argv);
}



MyRequestHandler.h
#pragma once

#include <Poco/Mutex.h>
#include <Poco/Util/ServerApplication.h>

using namespace Poco;
using namespace Poco::Util;
using namespace std;

class MyServerApp : public ServerApplication
{
public:
	static string getText();
	static void setText(string newText);

protected:
	int main(const vector<string> &);
	static string text;
	static Mutex textLock;
};



MyRequestHandler.cpp
#include <iostream>
#include <conio.h>
#include <string>

#include "MyRequestHandler.h"
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/ScopedLock.h>
#include <Poco/URI.h>
#include <Poco/StringTokenizer.h>

using namespace Poco::Net;

string MyServerApp::text = "Hello world!";
Mutex MyServerApp::textLock;

class CMyRequestHandler : public HTTPRequestHandler
{
public:
	void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp)
	{
		resp.setStatus(HTTPResponse::HTTP_OK);
		resp.setContentType("text/html");
		ostream& out = resp.send();

		URI uri(req.getURI());
		if (uri.toString().find("/setText") == 0)
		{
			StringTokenizer str(uri.getQuery(), "=");
			if (str.count() == 2 && str[0] == "text")
			{
				MyServerApp::setText(str[1]);
				out << "ok";
				out.flush();
				return;
			}
		}

		out << "error";
		out.flush();
	}
};

class MyRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
	virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest &)
	{
		return new CMyRequestHandler;
	}
};

void MyServerApp::setText(string newText)
{
	ScopedLock<Mutex> lock(textLock);
	text = newText;
}

string MyServerApp::getText() 
{ 
	ScopedLock<Mutex> lock(textLock);
	return text; 
}

int MyServerApp::main(const vector<string> &)
{
	HTTPServer s(new MyRequestHandlerFactory, ServerSocket(8000), new HTTPServerParams);
	s.start();
	for(;;)
	{
		cout << MyServerApp::getText() << endl;
		_getch();
	}
	s.stop();
	return Application::EXIT_OK;
}



Дополнительные материалы




Всем спасибо, удачи в использовании POCO.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

1

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции