解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# HttpServer ʹÓÃÊÖ²á
±¾Îĵµ»ùÓÚÔ´Âë `NewLife.Core/Http/HttpServer.cs`£¬ÓÃÓÚ˵Ã÷ `HttpServer`£¨ÇáÁ¿¼¶ HTTP ·þÎñÆ÷£©µÄÖ°Ôð¡¢Â·ÓÉ×¢²á·½Ê½¡¢Æ¥Å乿ÔòÓëʹÓÃ×¢ÒâÊÂÏî¡£
> ¹Ø¼ü´Ê£ºÂ·ÓÉÓ³É䡢ͨÅä·û `*`¡¢Î¯Íд¦ÀíÆ÷¡¢¿ØÖÆÆ÷Ó³Éä¡¢¾²Ì¬Îļþ¡¢Æ¥Å仺´æ¡¢Ḭ̈߳²È«¡£
---
## 1. ¸ÅÊö
`HttpServer` ¼Ì³Ð×Ô `NetServer` ²¢ÊµÏÖ `IHttpHost`£¬ÓÃÓÚÔÚ TCP Á¬½ÓÖ®ÉÏÌṩ HTTP ÐÒé´¦ÀíÄÜÁ¦¡£
Ö÷ÒªÖ°Ôð£º
1. ±£´æÂ·ÓÉÓ³Éä `Routes`£¬²¢ÔÚÊÕµ½ÇëÇóʱ¸ù¾Ý·¾¶Æ¥Åä `IHttpHandler`£»
2. Ϊÿ¸öÍøÂç»á»°´´½¨¶ÔÓ¦µÄ `HttpSession` ÐÒé´¦ÀíÆ÷£¨`CreateHandler`£©£»
3. Ìṩ¶àÖÖ `Map` ÖØÔØ£¨Î¯ÍÐ/¿ØÖÆÆ÷/¾²Ì¬Îļþ£©ÒÔ¼ò»¯×¢²á¡£
---
## 2. ĬÈÏÐÐΪÓë¹Ø¼üÊôÐÔ
### 2.1 »ù´¡ÅäÖÃ
¹¹Ô캯ÊýÖУ¬`HttpServer` µÄĬÈÏÅäÖÃΪ£º
- `Name = "Http"`
- `Port = 80`
- `ProtocolType = NetType.Http`
- `ServerName = "NewLife-HttpServer/{Major}.{Minor}"`£¨´Ó³ÌÐò¼¯°æ±¾Éú³É£©
### 2.2 `ServerName`
- ÀàÐÍ£º`String`
- ÓïÒ壺ÓÃÓÚ HTTP ÏìӦͷÖÐµÄ `Server` Ãû³Æ£¨¾ßÌåдÈëÓÉÐÒéÕ»ÆäËü²¿·ÖÍê³É£©¡£
### 2.3 `Routes`
- ÀàÐÍ£º`IDictionary<String, IHttpHandler>`
- Key£ºÂ·¾¶£¨Çø·Ö´óСд¹æÔò£º²»Çø·Ö£¬`StringComparer.OrdinalIgnoreCase`£©
- Value£º´¦ÀíÆ÷£¨`IHttpHandler`£©
˵Ã÷£º
- ·ÓÉ Key »áÔÚ×¢²áʱͳһȷ±£ÒÔ `/` ¿ªÍ·¡£
- ºó×¢²á»á¸²¸ÇÏÈ×¢²á£¨`Routes[path] = handler`£©¡£
---
## 3. »á»°ÓëÐÒé´¦Àí
### 3.1 `CreateHandler(INetSession session)`
`HttpServer` »áΪÿһ¸öµ×²ãÍøÂç»á»°´´½¨Ò»¸öÐ嵀 `HttpSession`£º
- ·µ»Ø£º`new HttpSession()`
ÕâÒâζ×Å£º
- HTTP ½âÎö¡¢ÇëÇó/ÏìÓ¦ÉúÃüÖÜÆÚÂß¼Ö÷ÒªÓÉ `HttpSession` ³Ðµ££»
- `HttpServer` ¸ü¾Û½¹ÔÚ¡°Â·Óɱíά»¤¡±ºÍ¡°Æ¥Åä´¦ÀíÆ÷¡±¡£
---
## 4. ·ÓÉ×¢²á API
`HttpServer` Ìṩ¶àÖÖ·ÓÉ×¢²á·½Ê½£¬×îÖÕͳһ×ß˽Óз½·¨ `SetRoute(String path, IHttpHandler handler)`¡£
### 4.1 Ó³Éä´¦ÀíÆ÷ʵÀý
```csharp
var server = new HttpServer();
server.Map("/api/test", new MyHandler());
```
- `Map(String path, IHttpHandler handler)`
### 4.2 Ó³ÉäίÍУ¨Delegate£©
ÊÊÓÃÓÚ¿ìËÙ×¢²áÇáÁ¿½Ó¿Ú¡£
- `Map(String path, HttpProcessDelegate handler)`
- `Map<TResult>(String path, Func<TResult> handler)`
- `Map<TModel, TResult>(String path, Func<TModel, TResult> handler)`
- `Map<T1, T2, TResult>(String path, Func<T1, T2, TResult> handler)`
- `Map<T1, T2, T3, TResult>(String path, Func<T1, T2, T3, TResult> handler)`
- `Map<T1, T2, T3, T4, TResult>(String path, Func<T1, T2, T3, T4, TResult> handler)`
˵Ã÷£º
- ÕâÐ©ÖØÔØ»á´´½¨ `DelegateHandler` ²¢°ÑίÍи³Öµµ½ `Callback`¡£
ʾÀý£º
```csharp
server.Map("/health", () => "OK");
```
### 4.3 Ó³Éä¿ØÖÆÆ÷
```csharp
server.MapController<MyController>();
```
- `MapController<TController>(String? path = null)`
- `MapController(Type controllerType, String? path = null)`
¹æÔò£º
- `path` Ϊ¿Õʱ£ºÄ¬ÈÏΪ `/{ControllerName}`£¬ÆäÖÐ ControllerName À´×Ô `controllerType.Name.TrimEnd("Controller")`¡£
- ¿ØÖÆÆ÷·ÓÉ×îÖջᱻ¹æ·¶»¯Îª£º`/{xxx}/*`¡£
- ×¢²áµÄ´¦ÀíÆ÷ÀàÐÍΪ `ControllerHandler`£¬Æä `ControllerType` Ö¸ÏòÄ¿±ê¿ØÖÆÆ÷ÀàÐÍ¡£
ʾÀý£º
```csharp
server.MapController<MyController>("/api");
// ʵ¼Ê×¢²á·ÓÉΪ /api/*
```
### 4.4 Ó³É侲̬ÎļþĿ¼
```csharp
server.MapStaticFiles("/js", "./wwwroot/js");
```
- `MapStaticFiles(String path, String contentPath)`
¹æÔò£º
- `path` »áÈ·±£ÒÔ `/` ¿ªÍ·£»
- ʵ¼ÊÓÃÓÚÆ¥ÅäµÄ·ÓÉ Key Ϊ `path.EnsureEnd("/").EnsureEnd("*")`£¬ÀýÈç `/js/*`£»
- `StaticFilesHandler.Path` Ϊ `path.EnsureEnd("/")`£¨ÀýÈç `/js/`£©£»
- `StaticFilesHandler.ContentPath` Ϊ´«ÈëµÄ `contentPath`¡£
---
## 5. ·ÓÉÉèÖù淶»¯£¨`SetRoute`£©
ËùÓзÓÉ×¢²á×îÖÕͳһµ½£º
- ²ÎÊýУÑ飺
- `path` ²»ÄÜΪ¿Õ
- `handler` ²»ÄÜΪ¿Õ
- ·¾¶¹æ·¶»¯£º
- `path = path.EnsureStart("/")`
- ¸²¸ÇÓïÒ壺
- `Routes[path] = handler`
×¢Ò⣺
- `SetRoute` ²»»á×Ô¶¯²¹Æëβ²¿ `/` »ò `*`£¬ÕâÓÉ `MapController` / `MapStaticFiles` ¸ºÔð¡£
---
## 6. ·ÓÉÆ¥Å乿Ôò£¨`MatchHandler`£©
`MatchHandler(String path, HttpRequest? request)` ÓÃÓÚ¸ù¾Ý¡°Òѹ淶»¯ºóµÄÇëÇó·¾¶£¨²»º¬²éѯ×Ö·û´®£©¡±Æ¥Åä´¦ÀíÆ÷¡£
Æ¥Åä˳Ðò£º
1. **¾«È·Æ¥Åä**£º`Routes.TryGetValue(path, out handler)`
2. **»º´æÃüÖÐ**£º
- `_pathCache.TryGetValue(path, out p)`
- È»ºó `Routes.TryGetValue(p, out handler)`
3. **ͨÅä·ûÆ¥Åä**£ºÃ¶¾Ù `Routes`£¬¶Ô°üº¬ `*` µÄ key Ö´ÐУº
- `key.IsMatch(path)`
### 6.1 ͨÅä·ûÔ¼¶¨
- ½öµ±Â·ÓÉ key °üº¬ `*` ʱ£¬²Å½øÈëÄ£ºýÆ¥Åä¡£
- Æ¥ÅäÂß¼ÒÀÀµ `IsMatch` À©Õ¹·½·¨£¨À´×Ô»ù´¡¿â×Ö·û´®Æ¥ÅäÄÜÁ¦£©¡£
### 6.2 Æ¥Å仺´æ `_pathCache`
- ÀàÐÍ£º`IDictionary<String, String>`
- Key£ºÇëÇó·¾¶ `path`
- Value£ºÃüÖеÄ·ÓÉ key£¨ÀýÈç `/api/*`£©
»º´æ²ßÂÔ£º
- ÃüÖÐ `StaticFilesHandler`£º»º´æ¸Ã `path -> routeKey`¡£
- ·Ç¾²Ì¬Îļþ£º½öµ± `path.Split('/')` ¶ÎÊý `<= 3` ²Å»º´æ¡£
Ä¿µÄ£º
- ±ÜÃ⶯̬ URL£¨ÀýÈç´ø¶à¶Î id µÄ·¾¶£©Ôì³É»º´æÎÞÏÞÅòÕÍ£»
- ¶Ô³£¼û¶Ì·¾¶¼ÓËÙÄ£ºýÆ¥Åä¡£
---
## 7. Ḭ̈߳²È«Óë²¢·¢×¢ÒâÊÂÏî
µ±Ç°ÊµÏֵIJ¢·¢ÓïÒ壺
- `Routes` ĬÈÏÊÇ `Dictionary`£¬²¢·Ç²¢·¢ÈÝÆ÷£»
- µäÐͳ¡¾°£ºÆô¶¯½×¶Î¼¯ÖÐ×¢²á·ÓÉ£¬ÔËÐÐÆÚÖ»¶Á·ÃÎÊ£»
- ÈôÔËÐÐÆÚ¶¯Ì¬Ôöɾ·ÓÉ£ºÐèÒªµ÷Ó÷½×ÔÐмÓËøÐòÁл¯·ÃÎÊ¡£
·çÏյ㣺
- ÔÚÔËÐÐÆÚÐÞ¸Ä `Routes` ²¢Í¬Ê±µ÷Óà `MatchHandler`£¬¿ÉÄÜ´¥·¢ `Dictionary` ö¾ÙÒì³£»ò²úÉú²»Ò»Ö½á¹û¡£
- `_pathCache` ͬÑùΪ `Dictionary`£¬²¢·¢¶ÁдҲ²»±£Ö¤°²È«¡£
½¨Ò飺
- Æô¶¯Íê³Éºó²»ÒªÔÙ±ä¸ü·ÓÉ£»
- »òÕßÔÚÍⲿ¼ÓËø£¬È·±£ `Map/SetRoute` Óë `MatchHandler` ²»²¢·¢Ö´ÐС£
---
## 8. ×îСʾÀý
> ˵Ã÷£ºÊ¾ÀýÖ»ÑÝʾ `HttpServer` µÄ·ÓÉ×¢²áÓë×éºÏ¡£Êµ¼ÊÆô¶¯¼àÌý¡¢»á»°ÊÕ·¢µÈÄÜÁ¦ÓÉ `NetServer` Ìṩ£¬ÇëÒÔÏîÄ¿ÄÚÏÖÓÐʾÀý»ò `NetServer` ÎĵµÎª×¼¡£
```csharp
using NewLife.Http;
var server = new HttpServer
{
Port = 8080,
ServerName = "MyServer/1.0",
};
server.Map("/health", () => "OK");
server.MapStaticFiles("/static", "./wwwroot");
server.MapController<MyController>("/api");
server.Start();
```
---
## 9. ³£¼ûÎÊÌâ
### 9.1 Ϊʲô `MapController` »á×Ô¶¯¼ÓÉÏ `/*`£¿
¿ØÖÆÆ÷ͨ³£ÐèҪƥÅäÆä¡°×Ó·¾¶¡±£¬ÀýÈç `/api/user/list`¡¢`/api/user/detail/123` µÈ¡£Í¨¹ý `/*` ÈÃͬһ¸ö¿ØÖÆÆ÷´¦ÀíÆ÷½Ó¹Ü¸Ãǰ׺ϵÄËùÓÐÇëÇó¡£
### 9.2 Ϊʲô²¿·Ö·¾¶²»×ö»º´æ£¿
¶Ô¶à¶Î¶¯Ì¬ URL È«Á¿»º´æ¿ÉÄܵ¼Ö `_pathCache` ³ÖÐøÔö³¤£¨»º´æÅòÕÍ£©¡£µ±Ç°²ßÂÔ½ö»º´æ¶Ì·¾¶»ò¾²Ì¬ÎļþÃüÖУ¬ÒÔʵÏÖ¼ÓËÙÓë¿Õ¼äÖ®¼äµÄÕÛÖС£
---
## 10. Ïà¹ØÔ´Âë
- `NewLife.Core/Http/HttpServer.cs`
- `NewLife.Core/Http/HttpSession.cs`
- `NewLife.Core/Http/Handlers/DelegateHandler.cs`£¨°´ÏîĿʵ¼Ê·¾¶Îª×¼£©
- `NewLife.Core/Http/Handlers/ControllerHandler.cs`
- `NewLife.Core/Http/Handlers/StaticFilesHandler.cs`
|