zenoh 是由rust编写的一个跨平台 网络中间件 ,支持 pub,sub,query。 提供多语言绑定。
据说性能稍逊于NNG。
一,编译 成 C dll
cmake 编译C dll
git clone https://github.com/eclipse-zenoh/zenoh-c.git
二,编译 C++ dll
cmake 编译 C++ dll 需要依赖第一步的 C dll
https://github.com/eclipse-zenoh/zenoh-cpp.git
三,demo
(1),将所有 编译出来的 dll /include/lib 放到一起

(2),客户端 cmake 文件 配置
需要引用c 和c++ 的cmake配置文件

(3),客户端
#include <iostream>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <map>
#include <mutex>
#include "zenoh.hxx"
using namespace zenoh;
struct Selector {
std::string key_expr;
std::string parameters;
};
int main(int, char **) {
init_log_from_env_or("error");
Config config = Config::create_default();
auto session = Session::open(std::move(config));
while (1){
// session.put("demo/example/simple", "Simple!");
std::this_thread::sleep_for(std::chrono::milliseconds (5000));
auto on_reply = [](const Reply &reply) {
if (reply.is_ok()) {
const auto &sample = reply.get_ok();
std::cout << "Received ('" << sample.get_keyexpr().as_string_view() << "' : '"
<< sample.get_payload().as_string() << "')\n";
} else {
std::cout << "Received an error :" << reply.get_err().get_payload().as_string() << "\n";
auto now = std::chrono::system_clock::now();
auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count();
std::cout << "Timestamp (ms): " << timestamp_ms << std::endl;
}
};
std::mutex m;
std::condition_variable done_signal;
bool done = false;
auto on_done = [&m, &done, &done_signal]() {
std::lock_guard lock(m);
std::cout<<"done ....."<<std::endl;
auto now = std::chrono::system_clock::now();
auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count();
std::cout << "Done Timestamp (ms): " << timestamp_ms << std::endl;
done = true;
done_signal.notify_all();
};
auto payload = std::string("payload123");
uint64_t timeout_ms = 1000;
QueryTarget query_target = zenoh::QueryTarget::Z_QUERY_TARGET_BEST_MATCHING;
Selector selector = Selector{std::string("demo/example/**"), ""};
Session::GetOptions options;
options.target = query_target;
if (!payload.empty()) {
options.payload = payload;
}
options.timeout_ms = timeout_ms;
session.get(selector.key_expr, selector.parameters, on_reply, on_done, std::move(options));
auto now = std::chrono::system_clock::now();
auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count();
std::cout << "Timestamp (ms): " << timestamp_ms << std::endl;
std::unique_lock lock(m);
done_signal.wait(lock, [&done] { return done; });
}
}
(4),服务端 cmake 配置

(5),服务端
#include <iostream>
#include "zenoh.hxx"
#include <chrono>
using namespace zenoh;
const char *kind_to_str(SampleKind kind) {
switch (kind) {
case SampleKind::Z_SAMPLE_KIND_PUT:
return "PUT";
case SampleKind::Z_SAMPLE_KIND_DELETE:
return "DELETE";
default:
return "UNKNOWN";
}
}
int main(int, char **) {
// 初始化日志级别
init_log_from_env_or("info");
// 初始化 Zenoh session
Config config = Config::create_default();
auto session = Session::open(std::move(config));
//订阅
KeyExpr keyexpr("demo/example/simple");
//auto queryable_keyexpr = KeyExpr("demo/example/simple_query");
auto data_handler = [](const Sample &sample) {
std::cout << ">> [Subscriber] Received " << kind_to_str(sample.get_kind()) << " ('"
<< sample.get_keyexpr().as_string_view() << "' : '" << sample.get_payload().as_string() << "')";
auto attachment = sample.get_attachment();
if (attachment.has_value()) {
std::cout << " (" << attachment->get().as_string() << ")";
}
std::cout << std::endl;
};
std::cout << "Declaring Subscriber on '" << keyexpr.as_string_view() << "'..." << std::endl;
auto subscriber = session.declare_subscriber(keyexpr, data_handler, closures::none);
//查询
auto keyexprQuery = KeyExpr("demo/example/simple_query");
auto payload = "payload456";
auto on_query = [payload, keyexprQuery](const Query &query) {
auto params = query.get_parameters();
auto query_payload = query.get_payload();
std::cout << ">> [Queryable ] Received Query '" << query.get_keyexpr().as_string_view() << "?" << params;
if (query_payload.has_value()) {
std::cout << "' with value = '" << query_payload->get().as_string();
}
std::cout << "'\n";
std::cout << "[Queryable ] Responding ('" << keyexprQuery.as_string_view() << "': '" << payload << "')\n";
auto now = std::chrono::system_clock::now();
auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count();
std::cout << "Timestamp (ms): " << timestamp_ms << std::endl;
query.reply(keyexprQuery, payload);
};
auto on_drop_queryable = []() { std::cout << "Destroying queryable\n"; };
Session::QueryableOptions opts;
opts.complete = "complete";
auto queryable = session.declare_queryable(keyexprQuery, on_query, on_drop_queryable, std::move(opts));
// 阻塞,不让进程退出
std::cin.get();
return 0;
}
(6),运行
这个中间件 同时也支持 C# rust java python 等
