From 0f7afc5f1de4a30bb1ea823a3af608e83fc397c2 Mon Sep 17 00:00:00 2001 From: Pierre Gabin FODOP GUMETE Date: Wed, 30 Jan 2019 15:33:12 +0100 Subject: [PATCH] IN PROGRESS: add C++ websocket client API --- src/afb-wsj1-test.cpp | 19 ++++++ src/afb-wsj1.compile | 8 +++ src/afb-wsj1.hpp | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 src/afb-wsj1-test.cpp create mode 100644 src/afb-wsj1.compile create mode 100644 src/afb-wsj1.hpp diff --git a/src/afb-wsj1-test.cpp b/src/afb-wsj1-test.cpp new file mode 100644 index 00000000..ff74b4b9 --- /dev/null +++ b/src/afb-wsj1-test.cpp @@ -0,0 +1,19 @@ +#include "afb-wsj1.hpp" + +void onreply(const char *value){ + std::cout << value << std::endl; + exit(0); +} + +int main(int ac, char **av){ + char*uri=av[1]; + char*api =av[2]; + char*verb =av[3]; + char*req =av[4]; + afb::wsj1 sj1; + char *x; + sj1.connect(uri); + sj1.call(api,verb,req,onreply); + std::cin>> x; + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/afb-wsj1.compile b/src/afb-wsj1.compile new file mode 100644 index 00000000..f830306f --- /dev/null +++ b/src/afb-wsj1.compile @@ -0,0 +1,8 @@ +g++ afb-wsj1-test.cpp -lsystemd -lafbwsc -I /opt/AGL/include -L /opt/AGL/lib -pthread +In file included from afb-wsj1-test.cpp:1:0: +afb-wsj1.hpp:21:0: warning: "_GNU_SOURCE" redefined + #define _GNU_SOURCE + +:0:0: note: this is the location of the previous definition + + diff --git a/src/afb-wsj1.hpp b/src/afb-wsj1.hpp new file mode 100644 index 00000000..2c18cf19 --- /dev/null +++ b/src/afb-wsj1.hpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2015-2018 "IoT.bzh" + * Author Gabin Fodop + * Author José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "json-c/json.h" +#include "afb-wsj1.h" +#include "afb-ws-client.h" +} + +#include +#include +#include +#include +#include + +#include + +namespace afb { + +class wsj1 { +public: + wsj1() noexcept = default; + wsj1(const wsj1 &other) = delete; + wsj1(wsj1 &&other) noexcept { wsj1_ = other.wsj1_; other.wsj1_ = nullptr; } + wsj1(const std::string &uri) { connect(uri); } + wsj1(const char *uri) { connect(uri); } + ~wsj1() { if (wsj1_) disconnect(); } + void connect(const std::string &uri) { connect(uri.c_str()); } + void connect(const char *uri); + void disconnect(); + void call(const char *api, const char *verb, char *request, std::function onreply); +#if 0 + void call(const char *api, const char *verb, json_object *request, std::function &onreply) + { + call(api,verb,json_object_to_json_string_ext(request,JSON_C_TO_STRING_PLAIN),[](const char *x){onreply(std::string(x));}); + }; + void call(const std::string &api, const std::string &verb, const std::string &request, std::function &onreply) + { + call(api.c_str(), verb.c_str(), request.c_str(), [=](const char *x){onreply(std::string(x));}); + } +#endif +public: + class msg { + friend class wsj1; + msg(afb_wsj1_msg *msg) : msg_{msg} {} + afb_wsj1_msg *msg_; + public: + }; +private: + afb_wsj1 *wsj1_ = nullptr; +private: + static struct afb_wsj1_itf wsj1_itf; + static void itf_hangup_(void *closure, struct afb_wsj1 *wsj1){}; + static void itf_on_call_(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg){}; + static void itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg); +private: + void on_hangup_(struct afb_wsj1 *wsj1); + void on_call_(const char *api, const char *verb, struct afb_wsj1_msg *msg); + void on_event_(const char *event, struct afb_wsj1_msg *msg); +private: + static sd_event *eloop_(); +private: + static void on_reply_(void *closure, struct afb_wsj1_msg *msg); +}; + +struct afb_wsj1_itf wsj1::wsj1_itf = { + wsj1::itf_hangup_, + wsj1::itf_on_call_, + wsj1::itf_on_event_ +}; + +void wsj1::connect(const char *uri) { + if (wsj1_) + throw std::runtime_error("already-connected"); + wsj1_ = afb_ws_client_connect_wsj1(eloop_(), uri, &wsj1_itf, reinterpret_cast(this)); + if (!wsj1_) + throw std::runtime_error("connection-failed"); +} + +void wsj1::disconnect() { + if (!wsj1_) + throw std::runtime_error("not-connected"); + afb_wsj1_unref(wsj1_); + wsj1_ = nullptr; +} + +void wsj1::itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg) { + reinterpret_cast(closure)->on_event_(event, msg); +} + +void wsj1::on_event_(const char *event, struct afb_wsj1_msg *msg) { + +} + +void wsj1::call(const char *api, const char *verb, char *request, std::function onreply) { + if (!wsj1_) + throw std::runtime_error("not-connected"); + std::function *onrep = new std::function(onreply); + afb_wsj1_call_s(wsj1_,api,verb,request,on_reply_,reinterpret_cast(onrep)); +} + +void wsj1::on_reply_(void *closure, struct afb_wsj1_msg *msg) { + std::function *onreply = reinterpret_cast*>(closure); + (*onreply)(afb_wsj1_msg_object_s(msg)); + afb_wsj1_msg_unref(msg); + delete onreply; +} + +sd_event *wsj1::eloop_() { + static sd_event *el = nullptr; + static std::mutex lock; + std::lock_guard guard(lock); + if (!el) { + if (sd_event_new(&el) == 0) { + std::thread t(sd_event_loop, el); + t.detach(); + } + } + return el; +} +void wsj1::on_hangup_(struct afb_wsj1 *wsj1) { + +}; +void wsj1::on_call_(const char *api, const char *verb, struct afb_wsj1_msg *msg) { + +}; + + +} +// faire un test qui verifi le fonctionnement de la classe, +// il faut faire bien attention avec la fonction call qui doit se terminer avan tle programme, un get char ou un cin +// ecrire lma fonction on reply qui affichhe le resultat de la requete à l'ecran \ No newline at end of file -- 2.16.6