Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to Zenoh V0.6.0-dev.0 #2

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

.idea
obj
bin

*.user
package/
50 changes: 31 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,57 @@
![zenoh banner](./zenoh-dragon.png)

[![NuGet](https://img.shields.io/nuget/v/Zenoh.svg)](https://www.nuget.org/packages/Zenoh)
[![Gitter](https://badges.gitter.im/atolab/zenoh.svg)](https://gitter.im/atolab/zenoh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![NuGet](https://img.shields.io/nuget/v/Zenoh-CS?color=blue)](https://www.nuget.org/packages/Zenoh-CS/)
[![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

# Eclipse zenoh C# API
# Zenoh C# API

[Eclipse zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol
that is able to scale down to extremely constrainded devices and networks.
[中文/chinese readme](https://github.com/sanri/zenoh-csharp/blob/master/README.zh.md)

[Zenoh](http://zenoh.io) is an extremely efficient and fault-tolerant [Named Data Networking](http://named-data.net) (NDN) protocol that is able to scale down to extremely constrainded devices and networks.

The C# API is for pure clients, in other terms does not support peer-to-peer communication,
can be easily tested against a zenoh router running in a Docker container (see https://zenoh.io/docs/getting-started/quick-test/).

The C# API is for pure clients, in other terms does not support peer-to-peer communication, can be easily tested against a zenoh router running in a Docker container (see https://github.com/eclipse-zenoh/zenoh#how-to-test-it).

-------------------------------
## How to install it

Requirements:
- The [zenoh-c](https://github.com/eclipse-zenoh/zenoh-c) library must be installed on your host

The Eclipse zenoh C# library is available on NuGet:
- The [zenoh-c](https://github.com/eclipse-zenoh/zenoh-c) library must be installed on your host
- The zenoh C# library [Zenoh-CS](https://www.nuget.org/packages/Zenoh-CS/) is available on NuGet(Only x64).

### Supported .NET Standards
- .NET 6.0
- .NET 7.0

### Supported CPU arch
- x64
- arm64 (untested)

The library is configured to target the **.NET Standard 2.0** at minimum.
### Mapping between Zenoh-CS and Zenoh-C versions
| Zenoh-C | Zenoh-CS |
|:---------:|:--------:|
| v0.7.2-rc | v0.1.* |


-------------------------------
## How to build it

Requirements:
Requirements:
* The [zenoh-c](https://github.com/eclipse-zenoh/zenoh-c) library must be installed on your host
* A .NET environment

Simply run `dotnet build Zenoh/`.
* A .NET environment. .NET6 or .NET7 [SDK](https://dotnet.microsoft.com/zh-cn/download/dotnet)

Build:
Because some of Zenoh-C data structures are not the same length in `x64` and `arm64`, you need to add the option `-p:Platform=x64` or `-p:Platform=ARM64` when building.
```shell
# x64 CPU
dotnet build Zenoh.csproj -c Release -p:Platform=x64
# arm64 CPU
dotnet build Zenoh.csproj -c Release -p:Platform=ARM64
```

-------------------------------
## Running the Examples

The examples are configured to target **net5.0**.

The simplest way to run some of the examples is to get a Docker image of the **zenoh** network router (see https://github.com/eclipse-zenoh/zenoh#how-to-test-it) and then to run the examples on your machine.

Then, run the zenoh-csharp examples following the instructions in [examples/Zenoh.Net/README.md](https://github.com/eclipse-zenoh/zenoh-csharp/blob/master/examples/Zenoh.Net/README.md)
Build and run the zenoh-csharp examples following the instructions in [examples/README.md](https://github.com/sanri/zenoh-csharp/blob/master/examples/README.md)
55 changes: 55 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
![zenoh banner](./zenoh-dragon.png)

[![NuGet](https://img.shields.io/nuget/v/Zenoh-CS?color=blue)](https://www.nuget.org/packages/Zenoh-CS/)
[![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

# Zenoh C# API

[Zenoh](http://zenoh.io)是一种非常高效和容错的命名数据网络([NDN](http://named-data.net))协议, 能够在非常受限制的设备和网络中运行.

C# API是用于纯客户端的, 可以很容易地针对运行在Docker容器中的zenoh路由器进行测试 (参考[快速测试](https://zenoh.io/docs/getting-started/quick-test/)).

-------------------------------
## 如何安装

需求:
- 库 [zenoh-c](https://github.com/eclipse-zenoh/zenoh-c) 必需被安装在你的主机上.
- Zenoh C# 库 [Zenoh-CS](https://www.nuget.org/packages/Zenoh-CS/) 库在NuGet上可用(只支持x64)

### 支持的 .NET 标准
- .NET 6.0
- .NET 7.0

### 支持的CPU架构
- x64
- arm64 (未测试)

### Zenoh-CS 版本与 Zenoh-C 版本对应关系
| Zenoh-C | Zenoh-CS |
|:---------:|:--------:|
| v0.7.2-rc | v0.1.* |


-------------------------------
## 如何构建

需求:
- 库 [zenoh-c](https://github.com/eclipse-zenoh/zenoh-c) 必需被安装在你的主机上.
- 主机安装有 .NET6 或 .NET7 的 [SDK](https://dotnet.microsoft.com/zh-cn/download/dotnet)

构建命令:
由于Zenoh-C的部分数据结构在 `x64` 与 `arm64` 下长度不一样, 所以构建时需要增加选项 `-p:Platform=x64` 或 `-p:Platform=ARM64`
```shell
# x64 CPU
dotnet build Zenoh.csproj -c Release -p:Platform=x64
# arm64 CPU
dotnet build Zenoh.csproj -c Release -p:Platform=ARM64
```


-------------------------------
## 运行示例

构建和运行示程序, 参考 [examples/README.zh.md](https://github.com/sanri/zenoh-csharp/blob/master/examples/README.zh.md)

166 changes: 166 additions & 0 deletions Zenoh/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#nullable enable

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Zenoh;

public class Config : IDisposable
{
public enum Mode
{
Peer,
Client,
}

internal unsafe ZOwnedConfig* ownedConfig;
private bool _disposed;


public Config()
{
unsafe
{
ZOwnedConfig config = ZenohC.z_config_default();
nint p = Marshal.AllocHGlobal(Marshal.SizeOf(config));
Marshal.StructureToPtr(config, p, false);
ownedConfig = (ZOwnedConfig*)p;
}

_disposed = false;
}

public static Config? LoadFromFile(string path)
{
unsafe
{
ZOwnedConfig config = ZenohC.zc_config_from_file(path);
int b = ZenohC.z_config_check(&config);
// if (!ZenohC.z_config_check(&config))
if (b==0)
{
ZenohC.z_config_drop(&config);
return null;
}

nint p = Marshal.AllocHGlobal(Marshal.SizeOf(config));
Marshal.StructureToPtr(config, p, false);
return new Config
{
ownedConfig = (ZOwnedConfig*)p,
_disposed = false,
};
}
}

public void Dispose() => Dispose(true);

private void Dispose(bool disposing)
{
if (_disposed) return;

unsafe
{
ZenohC.z_config_drop(ownedConfig);
Marshal.FreeHGlobal((nint)ownedConfig);
}

_disposed = true;
}

public string ToStr()
{
if (_disposed) return "";

unsafe
{
ZConfig config = ZenohC.z_config_loan(ownedConfig);
ZOwnedStr str = ZenohC.zc_config_to_string(config);
string o = ZenohC.ZOwnedStrToString(&str);
ZenohC.z_str_drop(&str);
return o;
}
}


public bool SetMode(Mode mode)
{
if (_disposed) return false;

string value = "";
switch (mode)
{
case Mode.Client:
value = "\"client\"";
break;
case Mode.Peer:
value = "\"peer\"";
break;
}

unsafe
{
ZConfig config = ZenohC.z_config_loan(ownedConfig);
sbyte r = ZenohC.zc_config_insert_json(config, ZenohC.zConfigModeKey, value);
return r == 0;
}
}

// The v such as "tcp/172.30.1.1:7447"
public bool SetConnect(string[] v)
{
if (_disposed) return false;

StringBuilder value = new StringBuilder("[");
foreach (var ele in v)
{
value.Append($"\"{ele}\",");
}

value.Append("]");

unsafe
{
ZConfig config = ZenohC.z_config_loan(ownedConfig);
sbyte r = ZenohC.zc_config_insert_json(config, ZenohC.zConfigConnectKey, value.ToString());
return r == 0;
}
}

// The v such as "tcp/127.0.0.1:7888"
public bool SetListen(string[] v)
{
if (_disposed) return false;

StringBuilder value = new StringBuilder("[");
foreach (var ele in v)
{
value.Append($"\"{ele}\",");
}

value.Append("]");

unsafe
{
ZConfig config = ZenohC.z_config_loan(ownedConfig);
sbyte r = ZenohC.zc_config_insert_json(config, ZenohC.zConfigListenKey, value.ToString());
return r == 0;
}
}

// Whether data messages should be timestamped
public bool SetTimestamp(bool b)
{
if (_disposed) return false;

string value = b ? "true" : "false";

unsafe
{
ZConfig config = ZenohC.z_config_loan(ownedConfig);
sbyte r = ZenohC.zc_config_insert_json(config, ZenohC.zConfigAddTimestampKey, value);
return r == 0;
}
}
}
82 changes: 82 additions & 0 deletions Zenoh/Id.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Zenoh;

public struct Id
{
internal byte[] data;

internal Id(ZId zid)
{
data = new byte[16];
for (int i = 0; i < 16; i++)
{
unsafe
{
data[i] = zid.id[i];
}
}
}

public string ToStr()
{
StringBuilder sb = new StringBuilder();
foreach (byte b in data)
{
sb.Append(b.ToString("x"));
}

return sb.ToString();
}
}

[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal unsafe struct ZIdBuffer
{
internal nuint count = 0;
internal fixed byte data[256 * 16];

public ZIdBuffer()
{
}

internal void Add(ZId* zId)
{
if (count >= 256) return;
for (nuint i = 0; i < 16; i++)
{
data[count * 16 + i] = zId->id[i];
}

count += 1;
}

internal Id[] ToIds()
{
Id[] ids = new Id[count];
for (nuint i = 0; i < count; i++)
{
byte[] o = new byte[16];
for (nuint j = 0; j < 16; j++)
{
o[j] = data[i * 16 + j];
}

Id id = new Id
{
data = o,
};
ids[i] = id;
}

return ids;
}

internal static void z_id_call(ZId* zId, void* context)
{
ZIdBuffer* pIdBuffer = (ZIdBuffer*)context;
pIdBuffer->Add(zId);
}
}
Loading