Skip to content

Commit b58a3b1

Browse files
Reymerclaude
andcommitted
[v1.1.0] 設備斷線偵測文件更新,Unity SDK 版本升至 1.1.0
- package.json: 1.0.0 → 1.1.0 - README: 新增 Device Id Key / Device Timeout Inspector 欄位說明,新增設備斷線偵測事件對比表與範例 - manual.html: Inspector 表格補上 Device Id Key / Device Timeout,新增「設備連線/斷線偵測」段落(OnDeviceStatus vs OnDeviceTimeout 比較表、範例程式碼、拔電情境說明);修正 UPM git URL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 751af75 commit b58a3b1

3 files changed

Lines changed: 96 additions & 18 deletions

File tree

README.md

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,32 +137,32 @@ Add `EdgeLinkManager` to any GameObject and configure in the Inspector:
137137
| TCP Host / Port | (TCP mode) EdgeLink Server IP and port |
138138
| Listen Port | (TCPListener mode) Local port Unity listens on |
139139
| UDP Local Port | (UDP mode) Local UDP port |
140+
| Device Id Key | Field name in the message that identifies the device (e.g. `id`). Leave empty to disable timeout tracking. |
141+
| Device Timeout (s) | Seconds without a message before a device is considered offline (`0` = disabled) |
142+
143+
### Reading Data
140144

141145
```csharp
142146
using UnityEngine;
143147

144148
public class Example : MonoBehaviour
145149
{
146-
public GameObject edgeLinkObject;
147-
148150
EdgeLinkManager edgeLink;
149151
string lastRaw;
150152

151153
void Start()
152154
{
153-
edgeLink = edgeLinkObject.GetComponent<EdgeLinkManager>();
155+
edgeLink = GetComponent<EdgeLinkManager>();
154156
}
155157

156158
void Update()
157159
{
158160
if (edgeLink.Raw == lastRaw) return;
159161
lastRaw = edgeLink.Raw;
160162

161-
string temp = edgeLink.Get("temp");
162-
string humid = edgeLink.Get("humid");
163-
string status = edgeLink.Get("status");
164-
165-
Debug.Log($"Temp:{temp} Humid:{humid} Status:{status}");
163+
string temp = edgeLink.Get("temp");
164+
string humid = edgeLink.Get("humid");
165+
Debug.Log($"Temp:{temp} Humid:{humid}");
166166
}
167167
}
168168
```
@@ -172,6 +172,33 @@ public class Example : MonoBehaviour
172172
| `Raw` | `string` | Latest raw message string (unparsed) |
173173
| `Get(key)` | `string` | Latest parsed value by field name, `null` if not found |
174174

175+
### Device Connect / Disconnect Detection
176+
177+
`EdgeLinkManager` provides two complementary disconnect mechanisms:
178+
179+
```csharp
180+
void Start()
181+
{
182+
edgeLink = GetComponent<EdgeLinkManager>();
183+
184+
// Fired when EdgeLink Server detects a TCP connection open/close (~15 s for power-cut)
185+
edgeLink.OnDeviceStatus += (connected, endpoint) =>
186+
Debug.Log(connected ? $"Online: {endpoint}" : $"Offline: {endpoint}");
187+
188+
// Fired when a specific device ID stops sending data for Device Timeout seconds
189+
edgeLink.OnDeviceTimeout += id => Debug.LogWarning($"{id} timed out");
190+
edgeLink.OnDeviceReconnected += id => Debug.Log($"{id} reconnected");
191+
}
192+
```
193+
194+
| Event | Trigger | Identifies by |
195+
|-------|---------|---------------|
196+
| `OnDeviceStatus` | EdgeLink Server detects TCP open/close | IP address |
197+
| `OnDeviceTimeout` | No message received for `Device Timeout (s)` | Device ID field |
198+
| `OnDeviceReconnected` | Message received again after timeout | Device ID field |
199+
200+
> **Power-cut scenario:** EdgeLink detects 3 missed PINGs (≈15 s) then fires `OnDeviceStatus(false, ...)`. After your configured timeout with no new messages, `OnDeviceTimeout` also fires.
201+
175202
---
176203

177204
## Arduino SDK
@@ -452,6 +479,7 @@ EdgeLink-Server/
452479
453480
| Version | Changes |
454481
|---------|---------|
482+
| v1.1.0 | Unity SDK — device connect/disconnect detection (`OnDeviceStatus`, `OnDeviceTimeout`, `OnDeviceReconnected`); fix STATUS endpoint to use stable IP; C#, Python, JavaScript SDKs added |
455483
| v1.0.0 | Initial release — .NET 8, HTTPS by default, PBKDF2, session persistence, rolling logger, CORS, Unity SDK |
456484
457485
---

SDK/Unity/Package/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.extrakyo.edgelink",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"displayName": "EdgeLink SDK",
55
"description": "Unity SDK for EdgeLink Server — TCP/UDP data receiving with automatic PING/PONG keepalive and mask-based message parsing.",
66
"unity": "2021.2",

Server/WebUI/manual.html

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ <h3>安裝(UPM Git URL)</h3>
13611361
<ol class="steps">
13621362
<li><div>開啟 Unity → <strong>Window → Package Manager</strong></div></li>
13631363
<li><div>點左上角 <strong>+ → Add package from git URL…</strong></div></li>
1364-
<li><div>輸入:<code>https://github.com/Reymer249/EdgeLink-Server.git?path=SDK/Unity/Package</code></div></li>
1364+
<li><div>輸入:<code>https://github.com/Reymer/EdgeLink-Server.git?path=SDK/Unity/Package#feature/dotnet-migration</code></div></li>
13651365
<li><div><strong>Add</strong>,等待 Unity 匯入完成</div></li>
13661366
<li><div>(選用)Package Manager → EdgeLink SDK → Samples → <strong>Import Basic Example</strong></div></li>
13671367
</ol>
@@ -1379,6 +1379,8 @@ <h3>Inspector 設定</h3>
13791379
<tr><td>TCP Port</td><td>(TCP 模式)EdgeLink TCP Client Port 號</td><td><code>9001</code></td></tr>
13801380
<tr><td>Listen Port</td><td>(TCPListener 模式)Unity 本地監聽 Port</td><td><code>9001</code></td></tr>
13811381
<tr><td>UDP Local Port</td><td>(UDP 模式)Unity 本地 UDP Port</td><td><code>9002</code></td></tr>
1382+
<tr><td>Device Id Key</td><td>訊息中代表設備 ID 的欄位名稱(例如 <code>id</code>);留空則不啟用超時追蹤</td><td><code>id</code></td></tr>
1383+
<tr><td>Device Timeout (s)</td><td>超過幾秒沒收到訊息視為設備離線(<code>0</code> = 停用)</td><td><code>20</code></td></tr>
13821384
</tbody>
13831385
</table></div>
13841386

@@ -1449,26 +1451,23 @@ <h3>使用範例</h3>
14491451

14501452
<span class="kw">public class</span> <span class="cls">Example</span> : <span class="cls">MonoBehaviour</span>
14511453
{
1452-
<span class="kw">public</span> <span class="cls">GameObject</span> edgeLinkObject;
1453-
14541454
<span class="cls">EdgeLinkManager</span> edgeLink;
14551455
<span class="kw">string</span> lastRaw;
14561456

14571457
<span class="kw">void</span> <span class="fn">Start</span>()
14581458
{
1459-
edgeLink = edgeLinkObject.<span class="fn">GetComponent</span>&lt;<span class="cls">EdgeLinkManager</span>&gt;();
1459+
edgeLink = <span class="fn">GetComponent</span>&lt;<span class="cls">EdgeLinkManager</span>&gt;();
14601460
}
14611461

14621462
<span class="kw">void</span> <span class="fn">Update</span>()
14631463
{
1464-
<span class="kw">if</span> (edgeLink.Raw == lastRaw) <span class="kw">return</span>; <span class="cmt">// 無新訊息則跳過</span>
1464+
<span class="kw">if</span> (edgeLink.Raw == lastRaw) <span class="kw">return</span>;
14651465
lastRaw = edgeLink.Raw;
14661466

1467-
<span class="kw">string</span> temp = edgeLink.<span class="fn">Get</span>(<span class="str">"temp"</span>);
1468-
<span class="kw">string</span> humid = edgeLink.<span class="fn">Get</span>(<span class="str">"humid"</span>);
1469-
<span class="kw">string</span> status = edgeLink.<span class="fn">Get</span>(<span class="str">"status"</span>);
1467+
<span class="kw">string</span> temp = edgeLink.<span class="fn">Get</span>(<span class="str">"temp"</span>);
1468+
<span class="kw">string</span> humid = edgeLink.<span class="fn">Get</span>(<span class="str">"humid"</span>);
14701469

1471-
Debug.<span class="fn">Log</span>(<span class="str">$"溫度:{temp} 濕度:{humid} 狀態:{status}"</span>);
1470+
Debug.<span class="fn">Log</span>(<span class="str">$"溫度:{temp} 濕度:{humid}"</span>);
14721471
}
14731472
}</code></pre>
14741473
</div>
@@ -1480,6 +1479,57 @@ <h3>使用範例</h3>
14801479
</div>
14811480
</div>
14821481

1482+
<h3>設備連線 / 斷線偵測</h3>
1483+
1484+
<p><code>EdgeLinkManager</code> 提供兩種互補的斷線偵測機制,可同時使用:</p>
1485+
1486+
<div class="table-wrap"><table>
1487+
<thead><tr><th>事件</th><th>觸發來源</th><th>識別單位</th><th>適用情境</th></tr></thead>
1488+
<tbody>
1489+
<tr>
1490+
<td><code>OnDeviceStatus(bool, string)</code></td>
1491+
<td>EdgeLink Server 偵測到 TCP 連線開/關</td>
1492+
<td>IP 位址</td>
1493+
<td>快速感知連線層斷線(含拔電約 15 秒)</td>
1494+
</tr>
1495+
<tr>
1496+
<td><code>OnDeviceTimeout(string)</code></td>
1497+
<td>Unity 本地計時,超過 Device Timeout 秒無訊息</td>
1498+
<td>設備 ID 欄位</td>
1499+
<td>多台設備共用一條連線,精確追蹤個別設備</td>
1500+
</tr>
1501+
<tr>
1502+
<td><code>OnDeviceReconnected(string)</code></td>
1503+
<td>超時後再次收到該設備訊息</td>
1504+
<td>設備 ID 欄位</td>
1505+
<td>設備重新上線通知</td>
1506+
</tr>
1507+
</tbody>
1508+
</table></div>
1509+
1510+
<div class="code-block">
1511+
<div class="code-header"><div class="dots"><div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div></div><span class="lang-tag">C# — 斷線偵測範例</span></div>
1512+
<pre><code><span class="kw">void</span> <span class="fn">Start</span>()
1513+
{
1514+
edgeLink = <span class="fn">GetComponent</span>&lt;<span class="cls">EdgeLinkManager</span>&gt;();
1515+
1516+
<span class="cmt">// TCP 連線層事件(由 EdgeLink Server 推送)</span>
1517+
edgeLink.OnDeviceStatus += (connected, endpoint) =>
1518+
Debug.<span class="fn">Log</span>(connected ? <span class="str">$"設備上線: {endpoint}"</span> : <span class="str">$"設備斷線: {endpoint}"</span>);
1519+
1520+
<span class="cmt">// 業務層事件(Unity 本地計時,依 Device Id Key 欄位追蹤)</span>
1521+
edgeLink.OnDeviceTimeout += id => Debug.<span class="fn">LogWarning</span>(<span class="str">$"{id} 離線(超時)"</span>);
1522+
edgeLink.OnDeviceReconnected += id => Debug.<span class="fn">Log</span>(<span class="str">$"{id} 重新上線"</span>);
1523+
}</code></pre>
1524+
</div>
1525+
1526+
<div class="callout info">
1527+
<div class="callout-body">
1528+
<strong>拔電斷線情境</strong>
1529+
設備突然斷電(無 FIN 封包)時,EdgeLink 透過 PING/PONG 機制偵測:連續 3 次 PING 無回應(約 15 秒)後,Server 強制關閉連線並推送 <code>OnDeviceStatus(false, …)</code>。之後若超過 <code>Device Timeout</code> 秒仍無訊息,<code>OnDeviceTimeout</code> 也會觸發。兩個事件一起使用可獲得最完整的斷線資訊。
1530+
</div>
1531+
</div>
1532+
14831533
<h3>TCP 模式拓樸(推薦)</h3>
14841534
<div class="topo">
14851535
<div class="topo-node green">IoT 設備(TCP 連入 EdgeLink)</div>

0 commit comments

Comments
 (0)