Skip to content

Commit 00056e4

Browse files
committed
Working GET call
1 parent 81a1a2d commit 00056e4

17 files changed

Lines changed: 24460 additions & 21 deletions

File tree

OpServer.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.platforms = { :ios => min_ios_version_supported }
1414
s.source = { :git => "https://github.com/OP-Engineering/op-server.git", :tag => "#{s.version}" }
1515

16-
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
16+
s.source_files = Dir.glob("ios/**/*.{h,hpp,m,mm}") + Dir.glob("cpp/**/*.{hpp,h,cpp,c}")
1717
s.private_header_files = "ios/**/*.h"
1818

1919
install_modules_dependencies(s)

cpp/Server.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#pragma once
2+
3+
#include "Server.hpp"
4+
#include "macros.hpp"
5+
#include <future>
6+
#include <iostream>
7+
8+
namespace opserver {
9+
10+
namespace jsi = facebook::jsi;
11+
namespace react = facebook::react;
12+
13+
Server::Server(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker) {
14+
15+
function_map["callback"] = HFN2(this, invoker) {
16+
const std::string method = args[0].asString(rt).utf8(rt);
17+
const std::string path = args[1].asString(rt).utf8(rt);
18+
auto callback = std::make_shared<jsi::Value>(rt, args[2]);
19+
20+
if (method == "GET") {
21+
server.Get(
22+
path, [this, &rt, invoker, callback](const httplib::Request &req,
23+
httplib::Response &res) {
24+
auto responseDone = std::make_shared<std::promise<std::string>>();
25+
auto responseFuture = responseDone->get_future();
26+
27+
invoker->invokeAsync([callback, responseDone](jsi::Runtime &rt) {
28+
try {
29+
auto promise = callback->asObject(rt).asFunction(rt).call(rt);
30+
31+
if (promise.isObject()) {
32+
auto promiseObj = promise.asObject(rt);
33+
auto then = promiseObj.getPropertyAsFunction(rt, "then");
34+
35+
// Create success handler
36+
auto successHandler = HFN(responseDone) {
37+
if (count > 0 && args[0].isString()) {
38+
responseDone->set_value(args[0].asString(rt).utf8(rt));
39+
} else {
40+
responseDone->set_value("Success!");
41+
}
42+
return jsi::Value::undefined();
43+
});
44+
45+
then.callWithThis(rt, promiseObj, successHandler);
46+
}
47+
} catch (const std::exception &e) {
48+
responseDone->set_value(std::string("Error: ") + e.what());
49+
}
50+
});
51+
52+
if (responseFuture.wait_for(std::chrono::seconds(5)) ==
53+
std::future_status::ready) {
54+
res.set_content(responseFuture.get(), "text/plain");
55+
} else {
56+
res.set_content("Timeout", "text/plain");
57+
}
58+
});
59+
60+
} else if (method == "POST") {
61+
server.Post(path,
62+
[callback](const httplib::Request &, httplib::Response &res) {
63+
res.set_content("Hello World!", "text/plain");
64+
});
65+
}
66+
67+
return {};
68+
});
69+
70+
// function_map["getIp"] = HFN(this) {
71+
// std::string ip;
72+
// int port;
73+
// // Get the local IP and port from the server socket
74+
// auto sock = server.socket();
75+
// if (sock != -1) {
76+
// detail::get_local_ip_and_port(sock, ip, port);
77+
// return jsi::String::createFromUtf8(rt, ip);
78+
// }
79+
//
80+
// return jsi::Value::undefined();
81+
// });
82+
83+
function_map["listen"] = HFN(this) {
84+
std::thread([this]() { server.listen("0.0.0.0", 3000); }).detach();
85+
return {};
86+
});
87+
}
88+
89+
std::vector<jsi::PropNameID> Server::getPropertyNames(jsi::Runtime &_rt) {
90+
std::vector<jsi::PropNameID> keys;
91+
keys.reserve(function_map.size());
92+
for (const auto &pair : function_map) {
93+
keys.emplace_back(jsi::PropNameID::forUtf8(_rt, pair.first));
94+
}
95+
return keys;
96+
}
97+
98+
jsi::Value Server::get(jsi::Runtime &rt, const jsi::PropNameID &propNameID) {
99+
const auto name = propNameID.utf8(rt);
100+
if (function_map.count(name) != 1) {
101+
return HFN(name) {
102+
throw std::runtime_error("[op-server] Function " + name +
103+
" not implemented");
104+
});
105+
}
106+
107+
return {rt, function_map[name]};
108+
}
109+
110+
void Server::set(jsi::Runtime &_rt, const jsi::PropNameID &name,
111+
const jsi::Value &value) {
112+
throw std::runtime_error("You cannot write to this object!");
113+
}
114+
115+
void Server::stop() {
116+
// http_server_
117+
}
118+
119+
Server::~Server() {
120+
121+
};
122+
123+
} // namespace opserver

cpp/Server.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include <ReactCommon/CallInvoker.h>
4+
#include <jsi/jsi.h>
5+
6+
#include <httplib.h>
7+
8+
namespace opserver {
9+
10+
namespace jsi = facebook::jsi;
11+
namespace react = facebook::react;
12+
13+
14+
class JSI_EXPORT Server : public jsi::HostObject {
15+
public:
16+
Server(jsi::Runtime &rt, std::shared_ptr<react::CallInvoker> invoker);
17+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
18+
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propNameID) override;
19+
void set(jsi::Runtime &rt, const jsi::PropNameID &name,
20+
const jsi::Value &value) override;
21+
void stop();
22+
~Server() override;
23+
24+
private:
25+
httplib::Server server;
26+
std::unordered_map<std::string, jsi::Value> function_map;
27+
};
28+
29+
} // namespace opserver

cpp/bindings.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "bindings.hpp"
2+
#include "Server.hpp"
3+
#include "macros.hpp"
4+
#include <string>
5+
#include <unordered_map>
6+
#include <vector>
7+
8+
namespace opserver {
9+
10+
namespace jsi = facebook::jsi;
11+
namespace react = facebook::react;
12+
13+
std::vector<std::shared_ptr<Server>> servers;
14+
15+
// React native will try to clean the module on JS context invalidation
16+
// (CodePush/Hot Reload) The clearState function is called
17+
void invalidate() {
18+
for (auto &server : servers) {
19+
if (server) {
20+
server->stop();
21+
}
22+
}
23+
servers.clear();
24+
}
25+
26+
void install(jsi::Runtime &rt,
27+
const std::shared_ptr<react::CallInvoker> &invoker) {
28+
29+
const auto create = HFN(invoker) {
30+
std::shared_ptr<Server> server = std::make_shared<Server>(rt, invoker);
31+
servers.emplace_back(server);
32+
return jsi::Object::createFromHostObject(rt, server);
33+
});
34+
35+
jsi::Object module = jsi::Object(rt);
36+
module.setProperty(rt, "create", create);
37+
38+
rt.global().setProperty(rt, "__OPServerProxy", std::move(module));
39+
}
40+
41+
} // namespace opserver

cpp/bindings.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <ReactCommon/CallInvoker.h>
4+
#include <jsi/jsi.h>
5+
#include <jsi/jsilib.h>
6+
7+
namespace opserver {
8+
9+
namespace jsi = facebook::jsi;
10+
namespace react = facebook::react;
11+
12+
void install(jsi::Runtime &rt,
13+
const std::shared_ptr<react::CallInvoker> &invoker);
14+
void invalidate();
15+
16+
} // namespace opserver

0 commit comments

Comments
 (0)