C ++ Enterprise Edition
ما هي "طبعة المؤسسة"

والمثير للدهشة أنه طوال الوقت الذي كنت أعمل فيه في مجال تكنولوجيا المعلومات ، لم أسمع أبدًا أي شخص يقول "إصدار المؤسسة" عن لغة برمجة ، باستثناء لغة Java. ولكن بعد كل شيء ، يكتب الأشخاص تطبيقات لشريحة الشركات بعدة لغات برمجة ، والكيانات التي يعمل عليها المبرمجون ، إن لم تكن متطابقة ، متشابهة. وبالنسبة لـ c ++ على وجه الخصوص ، أود أن أملأ الفجوة في ريادة الأعمال ، على الأقل أن أخبر عنها.
كما هو مطبق على C ++ ، "إصدار المؤسسة" هو مجموعة فرعية من اللغة والمكتبات التي تتيح لك "بسرعة" تطوير التطبيقات [عبر النظام الأساسي] لأنظمة وحدات مترابطة بشكل فضفاض مع بنية موزعة و / أو نظام تجميع ومع منطق عمل مطبق وكقاعدة عامة ، تحميل عالي.
لمتابعة حديثنا ، أولاً وقبل كل شيء ، من الضروري تقديم مفاهيم التطبيق والوحدة والمكونات الإضافية
- يعد التطبيق ملفًا قابلاً للتنفيذ يمكن أن يعمل كخدمة نظام ، وله تكوينه الخاص ، ويمكنه قبول معلمات الإدخال ، ويمكن أن يكون له هيكل مكون إضافي.
- الوحدة النمطية هي تطبيق واجهة تعيش داخل التطبيق أو منطق العمل.
- المكوّن الإضافي هو مكتبة محمّلة ديناميكيًا وتنفذ واجهة أو أكثر أو جزءًا من منطق العمل.
تحتاج جميع التطبيقات ، التي تؤدي أعمالها الفريدة ، إلى آليات على مستوى النظام ، مثل الوصول إلى البيانات (DBMS) ، وتبادل المعلومات عبر ناقل مشترك (JMS) ، وتنفيذ البرامج النصية الموزعة والمحلية مع الحفاظ على التناسق (المعاملات) ، ومعالجة الطلبات القادمة على سبيل المثال ، عبر بروتوكول http (s) (fastcgi) أو عبر websockets ، إلخ ... يجب أن يكون لكل تطبيق القدرة على تنظيم وحداته (OSGI) ، ويجب أن يكون في النظام الموزع القدرة على تنظيم التطبيقات.
مثال على نظام موزع ضعيف التوصيل

تطبيق
مثال على مخطط تطبيق وحدة خدمة الشركة.

لقد قدمت بالفعل تعريفا عاما للتطبيق ، لذلك دعونا نرى ما هو الآن في عالم C ++ لتنفيذ هذا المفهوم. كان أول من أظهر تطبيق التطبيق هو الأطر الرسومية مثل Qt و GTK ، ولكن إصدارات تطبيقهم افترضت في البداية أن التطبيق كان عبارة عن "نافذة" رسومية مع سياقها وفقط بعد فترة من الوقت ظهرت رؤية عامة للتطبيق ، بما في ذلك كخدمة نظام ، على سبيل المثال ، qtservice . لكنني لا أريد حقًا سحب إطار رسم مشروط لمهمة خدمة ، لذلك دعونا ننظر إلى المكتبات غير الرسومية. والدفع يتبادر إلى الذهن أولاً ... ولكن لسوء الحظ ، لا توجد Boost.Application وما شابه ذلك في قائمة المكتبات الرسمية. هناك مشروع منفصل Boost.Application . المشروع ممتع للغاية ، لكن في رأيي ، مطول ، على الرغم من احترام أيديولوجية التعزيز. هنا هو تطبيق مثال من Boost.Application
#define BOOST_ALL_DYN_LINK #define BOOST_LIB_DIAGNOSTIC #define BOOST_APPLICATION_FEATURE_NS_SELECT_BOOST #include <fstream> #include <iostream> #include <boost/application.hpp> using namespace boost; // my application code class myapp { public: myapp(application::context& context) : context_(context) {} void worker() { // ... while (st->state() != application::status::stopped) { boost::this_thread::sleep(boost::posix_time::seconds(1)); if (st->state() == application::status::paused) my_log_file_ << count++ << ", paused..." << std::endl; else my_log_file_ << count++ << ", running..." << std::endl; } } // param int operator()() { // launch a work thread boost::thread thread(&myapp::worker, this); context_.find<application::wait_for_termination_request>()->wait(); return 0; } bool stop() { my_log_file_ << "Stoping my application..." << std::endl; my_log_file_.close(); return true; // return true to stop, false to ignore } private: std::ofstream my_log_file_; application::context& context_; }; int main(int argc, char* argv[]) { application::context app_context; // auto_handler will automatically add termination, pause and resume (windows) // handlers application::auto_handler<myapp> app(app_context); // to handle args app_context.insert<application::args>( boost::make_shared<application::args>(argc, argv)); // my server instantiation boost::system::error_code ec; int result = application::launch<application::server>(app, app_context, ec); if (ec) { std::cout << "[E] " << ec.message() << " <" << ec.value() << "> " << std::endl; } return result; }
يعرّف المثال أعلاه تطبيق myapp
العامل الرئيسي وآلية تشغيل هذا التطبيق.
كإضافة ، سأقدم مثالًا مشابهًا من إطار pocoproject
#include <iostream> #include <sstream> #include "Poco/AutoPtr.h" #include "Poco/Util/AbstractConfiguration.h" #include "Poco/Util/Application.h" #include "Poco/Util/HelpFormatter.h" #include "Poco/Util/Option.h" #include "Poco/Util/OptionSet.h" using Poco::AutoPtr; using Poco::Util::AbstractConfiguration; using Poco::Util::Application; using Poco::Util::HelpFormatter; using Poco::Util::Option; using Poco::Util::OptionCallback; using Poco::Util::OptionSet; class SampleApp : public Application { public: SampleApp() : _helpRequested(false) {} protected: void initialize(Application &self) { loadConfiguration(); Application::initialize(self); } void uninitialize() { Application::uninitialize(); } void reinitialize(Application &self) { Application::reinitialize(self); } void defineOptions(OptionSet &options) { Application::defineOptions(options); options.addOption( Option("help", "h", "display help information on command line arguments") .required(false) .repeatable(false) .callback(OptionCallback<SampleApp>(this, &SampleApp::handleHelp))); } void handleHelp(const std::string &name, const std::string &value) { _helpRequested = true; displayHelp(); stopOptionsProcessing(); } void displayHelp() { HelpFormatter helpFormatter(options()); helpFormatter.setCommand(commandName()); helpFormatter.setUsage("OPTIONS"); helpFormatter.setHeader( "A sample application that demonstrates some of the features of the " "Poco::Util::Application class."); helpFormatter.format(std::cout); } int main(const ArgVec &args) { if (!_helpRequested) { logger().information("Command line:"); std::ostringstream ostr; logger().information(ostr.str()); logger().information("Arguments to main():"); for (const auto &it : args) { logger().information(it); } } return Application::EXIT_OK; } private: bool _helpRequested; }; POCO_APP_MAIN(SampleApp)
أود أن ألفت انتباهكم إلى حقيقة أن التطبيق يجب أن يحتوي على آليات لتسجيل وتنزيل التكوينات وخيارات المعالجة.
على سبيل المثال ، لمعالجة الخيارات هناك:
لتكوين:
لليوميات:
ضعف ، وحدات والإضافات.
الضعف في النظام "المشترك" هو إمكانية الاستبدال السريع وغير المؤلم لآليات معينة. ينطبق هذا على الوحدات النمطية داخل التطبيق وعلى التطبيقات نفسها ، وكذلك على التطبيقات ، على سبيل المثال ، الخدمات المجهرية. ماذا لدينا ، من وجهة نظر C ++. كل شيء سيئ مع الوحدات النمطية ، على الرغم من أنها تنفذ واجهات ، ولكنها تعيش داخل تطبيق "مترجم" ، لذلك لن يكون هناك تغيير سريع ، ولكن الإضافات تأتي إلى الإنقاذ! بمساعدة المكتبات الديناميكية ، لا يمكنك فقط تنظيم الاستبدال السريع ، ولكن أيضًا التشغيل المتزامن لإصدارين مختلفين. هناك عالم كامل من "استدعاء الإجراء البعيد" الملقب RPC. آليات البحث عن تطبيقات الواجهة ، إلى جانب RPC ، ولدت شيئا مشابها لـ OSGI من عالم Java. من الرائع الحصول على دعم لهذا في نظام C ++ البيئي ، وهناك مثال واحد ، إليك بعض الأمثلة:
وحدة نمطية ل "خادم التطبيق" POCO OSP
#include "Poco/OSP/BundleActivator.h" #include "Poco/OSP/BundleContext.h" #include "Poco/ClassLibrary.h" namespace HelloBundle { class BundleActivator: public Poco::OSP::BundleActivator { public: void start(Poco::OSP::BundleContext::Ptr pContext) { pContext->logger().information("Hello, world!"); } void stop(Poco::OSP::BundleContext::Ptr pContext) { pContext->logger().information("Goodbye!"); } }; }
وحدة نموذجية لـ Apache Celix "خادم التطبيقات"
#include "Bar.h" #include "BarActivator.h" using namespace celix::dm; DmActivator* DmActivator::create(DependencyManager& mng) { return new BarActivator(mng); } void BarActivator::init() { std::shared_ptr<Bar> bar = std::shared_ptr<Bar>{new Bar{}}; Properties props; props["meta.info.key"] = "meta.info.value"; Properties cProps; cProps["also.meta.info.key"] = "also.meta.info.value"; this->cExample.handle = bar.get(); this->cExample.method = [](void *handle, int arg1, double arg2, double *out) { Bar* bar = static_cast<Bar*>(handle); return bar->cMethod(arg1, arg2, out); }; mng.createComponent(bar) //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move) .addInterface<IAnotherExample>(IANOTHER_EXAMPLE_VERSION, props) .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps) .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit); }
تجدر الإشارة إلى أنه في الأنظمة الموزعة بشكل ضعيف ، من الضروري وجود آليات تضمن عمليات المعاملات ، لكن في الوقت الحالي لا يوجد شيء مماثل لـ C ++. أي مثلما لا توجد طريقة داخل تطبيق واحد لتقديم طلب إلى قاعدة البيانات والملف و esb في معاملة واحدة ، لا توجد طريقة من هذا القبيل للعمليات الموزعة. بالطبع ، يمكن كتابة كل شيء ، لكن لا يوجد شيء معمم. سيقول شخص ما أن هناك software transactional memory
، نعم ، بالطبع ، لكنها ستسهل فقط كتابة آليات المعاملة من تلقاء نفسها.
أدوات
من كل الأدوات المساعدة العديدة التي أريد تسليط الضوء على التسلسل و DSL ، بسببها وجودهم يسمح لك بتنفيذ العديد من المكونات والبرامج النصية الأخرى.
التسلسل
التسلسل هو عملية ترجمة بنية البيانات إلى سلسلة من البتات. إن عكس عملية التسلسل هو عملية إلغاء التسلسل (هيكلة) - استعادة الحالة الأولية لهيكل البيانات من تسلسل بت ويكيبيديا . في سياق C ++ ، من المهم أن نفهم أنه لا توجد اليوم طريقة لتسلسل الكائنات ونقلها إلى برنامج آخر لم يكن يعرف شيئًا من قبل عن هذا الكائن. في هذه الحالة ، أعني كائن كتطبيق لفئة معينة مع الحقول والأساليب. لذلك ، سوف أسلط الضوء على طريقتين رئيسيتين تستخدمان في عالم C ++:
- التسلسل إلى تنسيق ثنائي
- التسلسل إلى التنسيق الرسمي
في الأدب وعلى الإنترنت ، غالبًا ما يكون هناك فصل في التنسيق الثنائي والنص ، لكنني أعتقد أن هذا الفصل غير صحيح تمامًا ، على سبيل المثال ، لا يحفظ MsgPack معلومات حول نوع الكائن ، على التوالي ، يتم إعطاء التحكم للمبرمج لعرض التنسيق الصحيح ويكون التنسيق MsgPack ثنائيًا. على العكس من ذلك ، يحفظ Protobuf جميع المعلومات الوصفية في تمثيل وسيط ، مما يسمح باستخدامها بين لغات البرمجة المختلفة ، في حين أن Protobuf ثنائي أيضًا.
وبالتالي فإن عملية التسلسل ، لماذا نحن في حاجة إليها. للكشف عن جميع الفروق الدقيقة ، نحتاج إلى مقال آخر ، سأحاول شرحه بأمثلة. يسمح التسلسل ، مع الحفاظ على لغة البرمجة ، بـ "حزم" كيانات البرامج (الفئات ، الهياكل) لنقلها عبر الشبكة ، للتخزين المستمر ، على سبيل المثال ، في الملفات والبرامج النصية الأخرى ، والتي ، بدون تسلسل ، تجبرنا على اختراع بروتوكولاتنا الخاصة ومراعاة الأجهزة ومنصة البرامج ، ترميز النصوص ، إلخ.
فيما يلي بعض المكتبات النموذجية للتسلسل:
DSL
لغة المجال المحددة - لغة برمجة لمجال الموضوع الخاص بك. في الواقع ، عندما نشارك في أتمتة مؤسسة ما ، فإننا نواجه مجال موضوع العميل ونصف جميع العمليات التجارية من حيث مجال الموضوع ، ولكن بمجرد أن يتعلق الأمر بالبرمجة ، يشارك المبرمجون ، إلى جانب المحللين ، في رسم مفاهيم العمليات التجارية إلى مفاهيم الإطار ولغة البرمجة. وإذا لم يكن هناك عدد معين من العمليات التجارية ، وتم تعريف مجال الموضوع بدقة كافية ، فمن المنطقي إنشاء DSL الخاص بك ، لتنفيذ معظم السيناريوهات الحالية وإضافة أخرى جديدة. في عالم C ++ ، لا توجد العديد من الفرص للتطبيق "السريع" لـ DSL الخاص بك. هناك ، بالطبع ، آليات لتضمين lua و javascript ولغات البرمجة الأخرى في C ++ - برنامج ، لكن من يحتاج إلى نقاط ضعف ومحرك تنفيذ محتمل غير محكم لـ "كل شيء"؟! لذلك سوف نقوم بتحليل الأدوات التي تسمح لك بإجراء DSL بنفسك.
تم تصميم مكتبة Boost.Proto فقط لإنشاء DSL الخاص بك ، وهذا هو غرضه المباشر ، إليك مثال على ذلك
#include <iostream> #include <boost/proto/proto.hpp> #include <boost/typeof/std/ostream.hpp> using namespace boost; proto::terminal< std::ostream & >::type cout_ = { std::cout }; template< typename Expr > void evaluate( Expr const & expr ) { proto::default_context ctx; proto::eval(expr, ctx); } int main() { evaluate( cout_ << "hello" << ',' << " world" ); return 0; }
يتم استخدام Flex و Bison لإنشاء lexers ومحلل لقواعد اللغة الخاصة بك. بناء الجملة ليس بسيطًا ، لكنه يحل المشكلة بكفاءة.
رمز عينة لإنشاء lexer
%{ #include <math.h> %} DIGIT [0-9] ID [az][a-z0-9]* %% {DIGIT}+ { printf( "An integer: %s (%d)\n", yytext, atoi( yytext ) ); } {DIGIT}+"."{DIGIT}* { printf( "A float: %s (%g)\n", yytext, atof( yytext ) ); } if|then|begin|end|procedure|function { printf( "A keyword: %s\n", yytext ); } {ID} printf( "An identifier: %s\n", yytext ); "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); "{"[^}\n]*"}" /* eat up one-line comments */ [ \t\n]+ /* eat up whitespace */ . printf( "Unrecognized character: %s\n", yytext ); %% main( argc, argv ) int argc; char **argv; { ++argv, --argc; /* skip over program name */ if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; yylex(); }
ومع ذلك ، هناك مواصفات SCXML - State Chart XML: State Machine Notation for Control Abstraction ، وصف لجهاز الحالة في الترميز الشبيه بـ XML. هذا ليس بالضبط DSL ، ولكن أيضا آلية مريحة لأتمتة العمليات دون برمجة. Qt SCXML لديها تنفيذ ممتاز. هناك تطبيقات أخرى ، لكنها ليست مرنة للغاية.
هذا مثال على عميل FTP في تدوين SCXML ، مثال مأخوذ من موقع وثائق Qt
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" name="FtpClient" datamodel="ecmascript"> <state id="G" initial="I"> <transition event="reply" target="E"/> <transition event="cmd" target="F"/> <state id="I"> <transition event="reply.2xx" target="S"/> </state> <state id="B"> <transition event="cmd.DELE cmd.CWD cmd.CDUP cmd.HELP cmd.NOOP cmd.QUIT cmd.SYST cmd.STAT cmd.RMD cmd.MKD cmd.PWD cmd.PORT" target="W.general"/> <transition event="cmd.APPE cmd.LIST cmd.NLST cmd.REIN cmd.RETR cmd.STOR cmd.STOU" target="W.1xx"/> <transition event="cmd.USER" target="W.user"/> <state id="S"/> <state id="F"/> </state> <state id="W"> <onentry> <send eventexpr=""submit." + _event.name"> <param name="params" expr="_event.data"/> </send> </onentry> <transition event="reply.2xx" target="S"/> <transition event="reply.4xx reply.5xx" target="F"/> <state id="W.1xx"> <transition event="reply.1xx" target="W.transfer"/> </state> <state id="W.transfer"/> <state id="W.general"/> <state id="W.user"> <transition event="reply.3xx" target="P"/> </state> <state id="W.login"/> </state> <state id="P"> <transition event="cmd.PASS" target="W.login"/> </state> </state> <final id="E"/> </scxml>
وهكذا يبدو في متخيل SCXML

الوصول إلى البيانات والتكامل
ربما هذا هو واحد من أكثر المواضيع "قرحة" في العالم مع ++. إن عالم البيانات لمطور c ++ مرتبط دائمًا بالحاجة إلى أن يكون قادرًا على عرضها على جوهر لغة البرمجة. يوجد صف في جدول في كائن أو بنية ، json في صف وما إلى ذلك. في غياب التأمل - هذه مشكلة كبيرة ، لكننا ، مع ألقاب ++ ، لا نأسف ونجد طرقًا مختلفة للخروج من هذا الوضع. لنبدأ مع DBMS.
سوف أكون الآن مألوفًا ، لكن ODBC هو الآلية العالمية الوحيدة للوصول إلى قواعد بيانات قواعد البيانات العلائقية ، ولم يتم اختراع أي خيارات أخرى حتى الآن ، لكن C ++ - لا يقف المجتمع صامدًا وهناك اليوم مكتبات وأُطر عمل توفر واجهات وصول معممة إلى العديد من قواعد بيانات إدارة قواعد البيانات.
أولاً وقبل كل شيء ، سأذكر المكتبات التي توفر وصولاً موحدًا إلى قواعد البيانات باستخدام مكتبات العميل و SQL
جميعها جيدة ، لكنها تجعلك تتذكر الفروق الدقيقة في عرض البيانات من قاعدة البيانات إلى كائنات وهياكل C ++ ، بالإضافة إلى أن كفاءة استعلامات SQL تقع مباشرة على عاتقك.
الأمثلة التالية هي ORMs في C ++. نعم هناك! وبالمناسبة ، تدعم SOCI آليات ORM من خلال التخصص soci :: type_conversion ، لكنني لم أدرجها عن قصد ، لأن هذا ليس غرضها المباشر.
- LiteSQL C ++ - ORM ، والذي يسمح لك بالتفاعل مع DBMS SQLite3 و PostgreSQL و MySQL. تتطلب هذه المكتبة من المبرمج تصميم ملفات xml مسبقًا مع وصف للكائنات والعلاقات من أجل توليد مصادر إضافية باستخدام litesql-gen.
- ODB from Code Synthesis هو ORM ممتع للغاية ، فهو يسمح لك بالبقاء داخل C ++ ، دون استخدام ملفات الوصف الوسيط ، فيما يلي مثال صغير:
#pragma db object class person {
- Wt ++ هو إطار كبير ، يمكنك كتابة مقال منفصل حوله بشكل عام ، كما أنه يحتوي على ORM ، والذي يمكن أن يتفاعل مع DBMS Sqlite3 و Firebird و MariaDB / MySQL و MSSQL Server و PostgreSQL و Oracle.
- أود أيضًا أن أذكر ORM على sqlite sqlite_orm و hiberlite . نظرًا لأن sqlite عبارة عن DBMS مضمن ، وفحص ORM لأنها تحقق من الاستعلامات ، وبالتأكيد كل التفاعل مع قاعدة البيانات ، في وقت الترجمة ، تصبح الأداة مريحة للغاية للنشر السريع والنماذج الأولية.
- QHibernate - ORM لـ Qt5 بدعم Postgresql. غارقة في أفكار السبات من جافا.
على الرغم من أن التكامل من خلال DBMS يعتبر "تكامل" ، إلا أنني أفضل تركه خارج الأقواس والانتقال إلى التكامل من خلال البروتوكولات وواجهات برمجة التطبيقات.
RPC - استدعاء porocess عن بعد ، وهي تقنية معروفة لتفاعل "العميل" مع "الخادم". كما في حالة ORM ، تتمثل الصعوبة الرئيسية في كتابة / إنشاء ملفات مساعدة متنوعة لربط البروتوكول بالوظائف الحقيقية في الكود. لن أذكر عمداً مختلف RPCs المنفذة مباشرة في نظام التشغيل ، لكنني سأركز على حلول الأنظمة الأساسية.
- grpc هو إطار عمل من Google لإجراء مكالمات عن بُعد ، وهو إطار شائع وفعال للغاية من google. إنه يستخدم google protobuf أساسًا ، وقد ذكرته في قسم التسلسل ، وهو يدعم العديد من لغات البرمجة ، لكنه جديد على بيئة الشركة.
- json-rpc - RPC ، حيث يتم استخدام JSON كبروتوكول ، ومن الأمثلة الجيدة على التنفيذ مكتبة libjson-rpc-cpp ، فيما يلي مثال لملف الوصف:
[ { "name": "sayHello", "params": { "name": "Peter" }, "returns" : "Hello Peter" }, { "name" : "notifyServer" } ]
بناءً على هذا الوصف ، يتم إنشاء رمز العميل والخادم الذي يمكن استخدامه في التطبيق الخاص بك. بشكل عام ، هناك مواصفات لـ JSON-RPC 1.0 و 2.0 . لذلك ، استدعاء دالة من تطبيق ويب ، ومعالجتها في C ++ ليست صعبة.
- XML-RPC و SOAP - القائد الواضح هنا - هو gSOAP ، مكتبة قوية للغاية ، لا أعتقد أن هناك أي بدائل جديرة بها. كما في المثال السابق ، نقوم بإنشاء ملف وسيط يحتوي على محتوى xml-rpc أو صابون ، ونضع المولد عليه ، ونحصل على الكود ونستخدمه. أمثلة نموذجية للطلب والاستجابة في تدوين xml-rpc:
<?xml version="1.0"?> <methodCall> <methodName>examples.getState</methodName> <params> <param> <value><i4>41</i4></value> </param> </params> </methodCall> <methodResponse> <params> <param> <value><string>State-Ready</string></value> </param> </params> </methodResponse>
- Poco :: RemotingNG هو مشروع مثير للاهتمام للغاية من pocoproject. يسمح لك بتحديد الفئات والوظائف وما إلى ذلك. يمكن أن يسمى عن بعد باستخدام التعليقات التوضيحية في التعليقات. هنا مثال
typedef unsigned long GroupID; typedef std::string GroupName;
لإنشاء التعليمات البرمجية المساعدة ، يتم استخدام "برنامج التحويل البرمجي" الخاص به. لفترة طويلة كانت هذه الوظيفة موجودة فقط في النسخة المدفوعة من POCO Framework ، ولكن مع ظهور مشروع macchina.io ، يمكنك استخدامها مجانًا.
المراسلة مفهوم واسع إلى حد ما ، لكنني سأقوم بتحليله من وجهة نظر المراسلة عبر ناقل بيانات شائع ، وبالتحديد ، سأذهب إلى المكتبات والخوادم التي تنفذ خدمة رسائل Java باستخدام بروتوكولات مختلفة ، على سبيل المثال AMQP أو STOMP . يعد ناقل البيانات الشائع ، المعروف أيضًا باسم Enterprise Servise Bus (ESB) ، شائعًا جدًا في حلول قطاعات المؤسسات ، مثل يتيح لك دمج عناصر مختلفة من البنية التحتية لتكنولوجيا المعلومات فيما بينها بسرعة ، باستخدام نمط من نقطة إلى نقطة ومن اشتراك النشر. يوجد عدد قليل من وسطاء الرسائل الصناعية المكتوبة بلغة C ++ ، وأنا أعلم اثنين: Apache Qpid و UPMQ ، والثاني مكتوب من قبلي. هناك إكليبس موسكيتو ، لكنه مكتوب في سي. إن جمال JMS for java هو أن الكود الخاص بك لا يعتمد على البروتوكول الذي يستخدمه العميل والخادم ، JMS كـ ODBC ، ويعلن عن الوظائف والسلوك ، بحيث يمكنك تغيير موفر JMS مرة واحدة على الأقل في اليوم وعدم إعادة كتابة الكود ، من أجل C ++ ، للأسف ، ليست كذلك. سوف تضطر إلى إعادة كتابة جزء العميل لكل مزود. سأقوم ، في رأيي ، بإدراج مكتبات C ++ الأكثر شيوعًا لسماسرة الرسائل الأقل شيوعًا:
مبدأ أن هذه المكتبات توفر وظائف عامة يتوافق بشكل عام مع مواصفات JMS. في هذا الصدد ، هناك رغبة في تجميع مجموعة من الأشخاص المتشابهين في التفكير وكتابة نوع ما من ODBC ، ولكن لوسطاء الرسائل ، بحيث يعاني كل مبرمج C ++ أقل قليلاً من المعتاد.
اتصال الشبكة
تركت عمداً كل شيء كان مرتبطًا بشكل مباشر بتفاعل الشبكة حتى النهاية في هذا المجال ، لدى مطوري C ++ المشاكل الأقل ، في رأيي. يبقى فقط اختيار النمط الأقرب لقرارك ، والإطار الذي ينفذه. قبل إدراج المكتبات الأكثر شعبية ، أريد أن أشير إلى تفاصيل مهمة في تطوير تطبيقات الشبكة الخاصة بك. إذا قررت الخروج بالبروتوكول الخاص بك عبر TCP أو UDP ، فاستعد لأن جميع أنواع أدوات الأمان "الذكية" ستحظر حركة المرور الخاصة بك ، لذا كن حذرًا بشأن تعبئة البروتوكول ، على سبيل المثال ، في https أو قد تكون هناك مشاكل. حتى المكتبات:
- Boost.Asio و Boost.Beast - واحدة من أكثر التطبيقات شعبية للاتصال بالشبكة غير المتزامنة ، هناك دعم HTTP و WebSockets
- يعد Poco :: Net حلاً شائعًا للغاية ، وبالإضافة إلى التفاعل الأولي ، يمكنك استخدام فئات جاهزة من TCP Server Framework و Reactor Framework ، بالإضافة إلى فئات العميل والخادم من أجل HTTP و FTP والبريد الإلكتروني. هناك أيضا دعم ل WebSockets
- ACE - لم تستخدم هذه المكتبة مطلقًا ، لكن الزملاء يقولون إنها مكتبة مهمة أيضًا ، مع اتباع نهج متكامل لتنفيذ تطبيقات الشبكة والمزيد.
- شبكة كيو تي - في كيو تي ، يتم تنفيذ جزء الشبكة بشكل جيد. النقطة المثيرة للجدل الوحيدة هي الإشارات وفتحات لحلول الخادم ، على الرغم من أن الخادم في كيو تي !؟
في المجموع
لذا ، ما أردت قوله هو نظرة عامة على هذه المكتبات. إذا نجحت ، فلديك انطباع بأن هناك "إصدار مؤسسة" ، كما كان الحال ، ولكن لا توجد حلول لتنفيذه واستخدامه ، فقط حديقة حيوانات للمكتبات. لذلك هو حقا. هناك مكتبات كاملة أو أكثر لتطوير التطبيقات لقطاع الشركات ، لكن لا يوجد حل قياسي. بمفردي ، لا يمكنني إلا أن أوصي بـ pocoproject و maccina.io كنقطة انطلاق في البحث عن حلول للجهة الخلفية وتعزيز أي حالات ، وبالطبع أنا أبحث عن أشخاص متشابهين في التفكير لتعزيز مفهوم "C ++ Enterprise Edition"!