RPC远程过程调用,二进制封装,提供高吞吐低延迟的高性能RPC框架
|
# Api¿Í»§¶ËʹÓÃÊÖ²á
±¾Îĵµ½éÉÜ NewLife.Remoting ÖÐÓ¦Óÿͻ§¶Ë»ùÀà `ClientBase` µÄʹÓ÷½·¨£¬ÊÊÓÃÓÚÉ豸½ÓÈë¡¢Ó¦ÓöԽӵȳ¡¾°¡£
---
## 1. ¸ÅÊö
`ClientBase` ÊÇÓ¦Óÿͻ§¶ËµÄ³éÏó»ùÀ࣬ʵÏÖÁ˶ԽÓÄ¿±êƽ̨µÄµÇ¼¡¢ÐÄÌø¡¢¸üкÍÖ¸ÁîÏ·¢µÈ³¡¾°²Ù×÷¡£
### 1.1 µäÐÍÓ¦Óüܹ¹
| ¼Ü¹¹ | ÐÒé | ˵Ã÷ | ʾÀý |
|------|------|------|------|
| **RPCÓ¦Óüܹ¹** | TCP/UDP | ¿Í»§¶Ëͨ¹ý ApiClient Á¬½Ó·þÎñ¶Ë ApiServer£¬·þÎñ¶ËÖ±½ÓÏ·¢Ö¸Áî | ÂìÒϵ÷¶È |
| **HTTPÓ¦Óüܹ¹** | HTTP/HTTPS | ¿Í»§¶Ëͨ¹ý ApiHttpClient Á¬½Ó WebApi£¬·þÎñ¶Ëͨ¹ý WebSocket Ï·¢Ö¸Áî | ZeroIot É豸½ÓÈë |
| **OAuthÓ¦Óüܹ¹** | HTTP/HTTPS | ¿Í»§¶Ëͨ¹ý OAuth µÇ¼»ñÈ¡ÁîÅÆ£¬ºóÐøÇëÇóЯ´øÁîÅÆ | Ðdz¾ AppClient |
### 1.2 ºËÐŦÄÜ
- **µÇ¼ÈÏÖ¤**£ºÊ¹ÓñàÂëºÍÃÜÔ¿µÇ¼·þÎñ¶Ë£¬»ñÈ¡ÁîÅÆ
- **ÐÄÌø±£»î**£º¶¨Ê±Éϱ¨¿Í»§¶ËÐÔÄÜÊý¾Ý£¬Î¬³ÖÔÚÏß״̬
- **×Ô¶¯¸üÐÂ**£º¼ì²â²¢ÏÂÔØ¸üаü£¬×Ô¶¯Éý¼¶Ó¦ÓÃ
- **ÃüÁîÏ·¢**£º½ÓÊÕ²¢Ö´ÐзþÎñ¶ËÏ·¢µÄÃüÁî
- **ʼþÉϱ¨**£ºÏò·þÎñ¶ËÍÆË͸÷ÀàʼþÐÅÏ¢
---
## 2. ¿ìËÙ¿ªÊ¼
### 2.1 ´´½¨×Ô¶¨Òå¿Í»§¶Ë
¼Ì³Ð `ClientBase` ²¢ÊµÏÖÒµÎñÂß¼£º
```csharp
public class MyDeviceClient : ClientBase
{
public MyDeviceClient() : base()
{
// ÉèÖýӿÚ·¾¶Ç°×º
SetActions("Device/");
// ÆôÓù¦ÄÜÌØÐÔ
Features = Features.Login | Features.Logout | Features.Ping | Features.Notify;
}
public MyDeviceClient(IClientSetting setting) : base(setting)
{
SetActions("Device/");
Features = Features.Login | Features.Logout | Features.Ping | Features.Notify;
}
}
```
### 2.2 ÅäÖÿͻ§¶Ë
```csharp
var client = new MyDeviceClient
{
Server = "http://localhost:5000", // ·þÎñ¶ËµØÖ·
Code = "device001", // É豸±àÂë
Secret = "your_secret_key", // É豸ÃÜÔ¿
Timeout = 15_000, // ³¬Ê±Ê±¼ä£¨ºÁÃ룩
Log = XTrace.Log, // ÈÕÖ¾Êä³ö
};
```
### 2.3 Æô¶¯¿Í»§¶Ë
```csharp
// ·½Ê½Ò»£ºÒì²½´ò¿ª£¨ÍƼö£©
// ÔÚÍøÂçδ¾ÍÐ÷֮ǰ»á·´¸´³¢ÊԵǼ
client.Open();
// ·½Ê½¶þ£ºÖ±½ÓµÇ¼
await client.Login("MyApp");
```
### 2.4 ¹Ø±Õ¿Í»§¶Ë
```csharp
// ×¢Ïú²¢ÊÍ·Å×ÊÔ´
await client.Logout("Ó¦ÓùرÕ");
client.Dispose();
// »òÖ±½Ó Dispose£¨»á×Ô¶¯×¢Ïú£©
client.Dispose();
```
---
## 3. ¹¦ÄÜÌØÐÔ
ͨ¹ý `Features` ö¾Ù¿ØÖƿͻ§¶Ë¹¦ÄÜ£º
| ÌØÐÔ | ˵Ã÷ |
|------|------|
| `Login` | µÇ¼¹¦ÄÜ |
| `Logout` | ×¢Ïú¹¦ÄÜ |
| `Ping` | ÐÄÌø¹¦ÄÜ |
| `Upgrade` | ×Ô¶¯¸üй¦ÄÜ |
| `Notify` | ÏÂÐÐ֪ͨ£¨WebSocket³¤Á¬½Ó£© |
| `CommandReply` | ÃüÁîÏìÓ¦Éϱ¨ |
| `PostEvent` | ʼþÉϱ¨¹¦ÄÜ |
| `All` | ÆôÓÃÈ«²¿¹¦ÄÜ |
```csharp
// ÆôÓöà¸ö¹¦ÄÜ
client.Features = Features.Login | Features.Logout | Features.Ping | Features.Notify;
// ÆôÓÃÈ«²¿¹¦ÄÜ
client.Features = Features.All;
```
---
## 4. µÇ¼ÓëÈÏÖ¤
### 4.1 »ù±¾µÇ¼
```csharp
// µÇ¼²¢»ñÈ¡ÏìÓ¦
var response = await client.Login("À´Ô´±êʶ");
if (client.Logined)
{
Console.WriteLine($"µÇ¼³É¹¦£¬ÁîÅÆ£º{response?.Token}");
}
```
### 4.2 ×Ô¶¨ÒåµÇ¼ÇëÇó
ÖØÐ´ `BuildLoginRequest` ·½·¨Ìí¼Ó×Ô¶¨Òå²ÎÊý£º
```csharp
public class MyDeviceClient : ClientBase
{
public String ProductKey { get; set; }
public override ILoginRequest BuildLoginRequest()
{
var request = base.BuildLoginRequest();
// Ìí¼Ó×Ô¶¨Òå²ÎÊý
if (request is MyLoginRequest myRequest)
{
myRequest.ProductKey = ProductKey;
}
return request;
}
}
```
### 4.3 µÇ¼³É¹¦Ê¼þ
```csharp
client.OnLogined += (sender, e) =>
{
var request = e.Request;
var response = e.Response;
Console.WriteLine($"µÇ¼³É¹¦£º{response.Code}");
// ´¦Àí·þÎñ¶ËÏ·¢µÄ±àÂëºÍÃÜÔ¿£¨×Ô¶¯×¢²á³¡¾°£©
if (!response.Code.IsNullOrEmpty())
{
// ±£´æÐµıàÂëºÍÃÜÔ¿
}
};
```
### 4.4 ÃÜÂë±£»¤
ʹÓà `IPasswordProvider` ±£»¤ÃÜÂë´«Ê䣺
```csharp
client.PasswordProvider = new SaltPasswordProvider
{
Algorithm = "md5",
SaltTime = 60
};
```
---
## 5. ÐÄÌøÓë±£»î
### 5.1 ×Ô¶¯ÐÄÌø
µÇ¼³É¹¦ºó£¬¿Í»§¶Ë»á×Ô¶¯Æô¶¯ÐÄÌø¶¨Ê±Æ÷£¬Ä¬Èϼä¸ô 60 Ãë¡£
### 5.2 ÊÖ¶¯ÐÄÌø
```csharp
var response = await client.Ping();
if (response != null)
{
Console.WriteLine($"ÐÄÌø³É¹¦£¬·þÎñÆ÷ʱ¼äÆ«ÒÆ£º{client.Span}");
}
```
### 5.3 ×Ô¶¨ÒåÐÄÌøÊý¾Ý
ÖØÐ´ `BuildPingRequest` »ò `FillPingRequest` Ìí¼Ó×Ô¶¨ÒåÊý¾Ý£º
```csharp
public override IPingRequest BuildPingRequest()
{
var request = base.BuildPingRequest();
// Ìí¼Ó×Ô¶¨ÒåÊý¾Ý
if (request is MyPingRequest myRequest)
{
myRequest.CustomData = GetCustomData();
}
return request;
}
```
### 5.4 ÐÄÌøÊý¾Ý˵Ã÷
ĬÈÏÐÄÌø»áÉϱ¨ÒÔÏÂÐÔÄÜÊý¾Ý£º
| ×Ö¶Î | ˵Ã÷ |
|------|------|
| `Memory` | ÄÚ´æ´óС |
| `AvailableMemory` | ¿ÉÓÃÄÚ´æ |
| `CpuRate` | CPU Õ¼ÓÃÂÊ |
| `Temperature` | ÎÂ¶È |
| `Battery` | µçÁ¿ |
| `TotalSize` | ´ÅÅÌ´óС |
| `AvailableFreeSpace` | ´ÅÅÌ¿ÉÓÿռä |
| `IP` | ±¾µØ IP µØÖ· |
| `Uptime` | ÔËÐÐʱ¼ä£¨Ã룩 |
| `Delay` | ÍøÂçÑÓ³Ù£¨ºÁÃ룩 |
---
## 6. ÃüÁî´¦Àí
### 6.1 ×¢²áÃüÁî´¦ÀíÆ÷
```csharp
// ·½Ê½Ò»£º¼òµ¥×Ö·û´®²ÎÊý
client.RegisterCommand("Reboot", (String? args) =>
{
Console.WriteLine($"ÊÕµ½ÖØÆôÃüÁ{args}");
return "ÖØÆô³É¹¦";
});
// ·½Ê½¶þ£ºÒì²½´¦Àí
client.RegisterCommand("UpdateConfig", async (String? args) =>
{
await UpdateConfigAsync(args);
return "ÅäÖøüгɹ¦";
});
// ·½Ê½Èý£ºÍêÕûÃüÁîÄ£ÐÍ
client.RegisterCommand("Execute", (CommandModel model) =>
{
return new CommandReplyModel
{
Id = model.Id,
Status = CommandStatus.ÒÑÍê³É,
Data = "Ö´Ðгɹ¦"
};
});
// ·½Ê½ËÄ£ºÒì²½ + È¡ÏûÁîÅÆ
client.RegisterCommand("LongTask", async (CommandModel model, CancellationToken ct) =>
{
await DoLongTaskAsync(model.Argument, ct);
return new CommandReplyModel
{
Id = model.Id,
Status = CommandStatus.ÒÑÍê³É
};
});
```
### 6.2 ÃüÁîʼþ
```csharp
client.Received += (sender, e) =>
{
var model = e.Model;
Console.WriteLine($"ÊÕµ½ÃüÁ{model.Command}£¬²ÎÊý£º{model.Argument}");
// ¿ÉÒÔÐÞ¸ÄÃüÁî»òÉèÖÃ×Ô¶¨ÒåÏìÓ¦
e.Reply = new CommandReplyModel
{
Id = model.Id,
Status = CommandStatus.ÒÑÍê³É,
Data = "´¦ÀíÍê³É"
};
};
```
### 6.3 Ö÷¶¯·¢ËÍÃüÁî
```csharp
// ÏòÃüÁîÒýÇæ·¢ËÍÃüÁ´¥·¢ÒÑ×¢²áµÄ´¦ÀíÆ÷
var reply = await client.SendCommand("Reboot", "Á¢¼´ÖØÆô");
```
### 6.4 ÃüÁî״̬
| ״̬ | ˵Ã÷ |
|------|------|
| `¾ÍÐ÷` | µÈ´ýÖ´ÐÐ |
| `´¦ÀíÖÐ` | ÕýÔÚÖ´ÐÐ |
| `ÒÑÍê³É` | Ö´Ðгɹ¦ |
| `´íÎó` | Ö´ÐÐʧ°Ü |
| `È¡Ïû` | ÒÑÈ¡Ïû |
---
## 7. ʼþÉϱ¨
### 7.1 Éϱ¨Ê¼þ
```csharp
// Éϱ¨ÐÅϢʼþ
client.WriteInfoEvent("DeviceStart", "É豸Æô¶¯³É¹¦");
// Éϱ¨´íÎóʼþ
client.WriteErrorEvent("SensorError", "ζȴ«¸ÐÆ÷Òì³£");
// Éϱ¨×Ô¶¨ÒåÀàÐÍʼþ
client.WriteEvent("alert", "HighTemperature", "ζȳ¬¹ýãÐÖµ£º85¡ãC");
```
### 7.2 ʼþÀàÐÍ
| ÀàÐÍ | ˵Ã÷ |
|------|------|
| `info` | ÐÅϢʼþ |
| `alert` | ¸æ¾¯Ê¼þ |
| `error` | ´íÎóʼþ |
### 7.3 ÅúÁ¿Éϱ¨
ʼþ»á×Ô¶¯»º´æ²¢ÅúÁ¿Éϱ¨£¬Ä¬Èϼä¸ô 60 Ã룬ÿÅú×î¶à 100 Ìõ¡£
```csharp
// Ö±½ÓÅúÁ¿Éϱ¨
await client.PostEvents(new EventModel[]
{
new() { Type = "info", Name = "Event1", Remark = "ʼþ1" },
new() { Type = "info", Name = "Event2", Remark = "ʼþ2" },
});
```
---
## 8. ×Ô¶¯¸üÐÂ
### 8.1 ÆôÓøüй¦ÄÜ
```csharp
client.Features |= Features.Upgrade;
```
### 8.2 ÊÖ¶¯¼ì²é¸üÐÂ
```csharp
var info = await client.Upgrade("stable"); // Ö¸¶¨¸üÐÂͨµÀ
if (info != null)
{
Console.WriteLine($"·¢ÏÖа汾£º{info.Version}");
}
```
### 8.3 ¸üÐÂÁ÷³Ì
1. µ÷Ó÷þÎñ¶Ë½Ó¿Ú²éѯ¸üÐÂÐÅÏ¢
2. ÏÂÔØ¸üаü
3. УÑéÎļþ¹þÏ£
4. ½âѹ²¢¸²¸ÇÎļþ
5. Ö´ÐÐÔ¤°²×°½Å±¾£¨¿ÉÑ¡£©
6. Ç¿ÖÆ¸üÐÂʱ×Ô¶¯ÖØÆô
---
## 9. Ô¶³Ìµ÷ÓÃ
### 9.1 µ÷Ó÷þÎñ¶Ë½Ó¿Ú
```csharp
// Òì²½µ÷ÓÃ
var result = await client.InvokeAsync<MyResponse>("Device/GetInfo", new { id = 123 });
// ͬ²½µ÷ÓÃ
var result = client.Invoke<MyResponse>("Device/GetInfo", new { id = 123 });
// GET ÇëÇ󣨽ö HTTP£©
var result = await client.GetAsync<MyResponse>("Device/GetStatus", new { id = 123 });
```
### 9.2 ×Ô¶¯ÖØÐµÇ¼
µ±ÁîÅÆ¹ýÆÚ£¨·þÎñ¶Ë·µ»Ø 401£©Ê±£¬¿Í»§¶Ë»á×Ô¶¯ÖØÐµÇ¼²¢ÖØÊÔÇëÇó¡£
---
## 10. ʱ¼äͬ²½
¿Í»§¶Ë»á×Ô¶¯¼ÆËãÓë·þÎñÆ÷µÄʱ¼ä²î£¬Í¨¹ý `GetNow()` »ñȡУ׼ºóµÄʱ¼ä£º
```csharp
// »ñÈ¡»ùÓÚ·þÎñÆ÷µÄµ±Ç°Ê±¼ä
var serverTime = client.GetNow();
// ʱ¼ä²î£¨·þÎñÆ÷ʱ¼ä - ¿Í»§¶Ëʱ¼ä£©
var span = client.Span;
// ÍøÂçÑÓ³Ù£¨ºÁÃ룩
var delay = client.Delay;
```
---
## 11. ÈÕÖ¾Óë×·×Ù
### 11.1 ÅäÖÃÈÕÖ¾
```csharp
client.Log = XTrace.Log;
```
### 11.2 Á´Â·×·×Ù
```csharp
client.Tracer = new DefaultTracer();
```
---
## 12. ¿Í»§¶ËÉèÖÃ
ʵÏÖ `IClientSetting` ½Ó¿Ú³Ö¾Ã»¯ÅäÖãº
```csharp
public class DeviceSetting : IClientSetting
{
public String Server { get; set; } = "http://localhost:5000";
public String Code { get; set; } = "";
public String? Secret { get; set; }
public void Save()
{
// ±£´æµ½Îļþ»òÊý¾Ý¿â
File.WriteAllText("config.json", this.ToJson());
}
}
```
ʹÓÃÉèÖãº
```csharp
var setting = new DeviceSetting { Server = "http://localhost:5000" };
var client = new MyDeviceClient(setting);
```
---
## 13. ¸ß¼¶Ó÷¨
### 13.1 ×Ô¶¨Òå½Ó¿Ú·¾¶
```csharp
protected override void SetActions(String prefix)
{
base.SetActions(prefix);
// Ìí¼Ó×Ô¶¨Òå½Ó¿Ú
Actions[MyFeatures.CustomAction] = prefix + "CustomAction";
}
```
### 13.2 ×Ô¶¨Òå HTTP ¿Í»§¶Ë
```csharp
protected override ApiHttpClient CreateHttp(String urls)
{
var http = base.CreateHttp(urls);
// ×Ô¶¨ÒåÅäÖÃ
http.Timeout = 30_000;
http.DefaultUserAgent = "MyApp/1.0";
return http;
}
```
### 13.3 WebSocket ³¤Á¬½Ó
ÆôÓà `Notify` ÌØÐԺ󣬿ͻ§¶Ë»á×Ô¶¯½¨Á¢ WebSocket ³¤Á¬½Ó½ÓÊÕ·þÎñ¶ËÍÆËÍ£º
```csharp
client.Features |= Features.Notify;
```
---
## 14. ×î¼Ñʵ¼ù
1. **ʹÓÃÒÀÀµ×¢Èë**£ºÔÚ ASP.NET Core ÖÐ×¢²áΪµ¥Àý·þÎñ
2. **ÅäÖó־û¯**£ºÊµÏÖ `IClientSetting` ±£´æ×Ô¶¯×¢²áµÄ±àÂëºÍÃÜÔ¿
3. **ÈÕÖ¾×·×Ù**£ºÅäÖà `Log` ºÍ `Tracer` ±ãÓÚÎÊÌâÅŲé
4. **ÓÅÑŹرÕ**£ºµ÷Óà `Dispose()` È·±£ÕýÈ·×¢ÏúºÍÊÍ·Å×ÊÔ´
5. **ÃüÁîÃݵÈ**£ºÃüÁî´¦ÀíÆ÷Ó¦Ö§³ÖÖØ¸´Ö´ÐÐ
6. **Òì³£´¦Àí**£º²¶»ñ `ApiException` ´¦ÀíÒµÎñÒì³£
---
## 15. ʾÀýÏîÄ¿
²Î¿¼ `Samples` Ŀ¼ÏµÄʾÀýÏîÄ¿£º
- **IoTZero**£ºÎïÁªÍøÉ豸½ÓÈëʾÀý
- **Demo**£º»ù´¡¹¦ÄÜÑÝʾ
- **Zero.Desktop**£º×ÀÃæÓ¦ÓÃʾÀý
- **ZeroServer**£º·þÎñ¶ËʾÀý
---
£¨Í꣩
|