我從事手機app服務端開發現在已經是3個年頭,自己也整理出了一套相對好用的服務架構,寫出來,跟大家一起分享。如有不足,還請多指教。
一:基礎流程圖。
其實有一點還需要加上,就是對json的壓縮和加密,一來給用戶節約流量,二來防止請求被截取破解我們的參數。具體先壓縮后加密還是先加密后壓縮這個問題看需求。
看到這個架構設計時,你們可能會說如果程序入口掛了,所有的服務都不可以用了。
所以這個架構的弱點在程序入口處,因此要有一(多)台機器做負載,負載的工具可以是HaProxy(軟件)或者F5(硬件)的負載。F5比較昂貴,我沒用過,haproxy的配置我就不貼了,谷歌一大把。
二:Json參數設計
手機App的靈魂是用戶數,有了用戶數才有一切。據我得到的數據,一款App的成功大部分取決於渠道推廣。而一款手機的mac.imsi等數據是唯一標識一個手機用戶的標准。可能某個用戶換了一款手機,但是還想用以前的賬號登錄,所以userID也是必不可少的字段。但是會出現一個問題,兩個mac.imsi,userID,但是他是一個用戶,所以對用戶信息的更新是至關重要的。但是用戶數據的更新不可能放在客戶端,當你界面提供了上傳imsi.mac.phonenumber等字段到服務端時,用戶會義無反顧的選擇否。如果你偷偷上傳用戶的隱私數據到數據庫,這是國內通用做法。不排除被用戶控告的可能性。所以我們要想一起兩全其美的辦法。每一次都把這些信息上傳上去,美其名曰:唯一標識用戶。至於其它的數據,那是運營哥需要的數據,可以在數據中加上。
{
"context": {
"userID": "1",
"pwd": "fuckGfw",
"imei": "353641012835017",
"imsi": "460000000000000"
},
"reqType": {
"rt": "xxx"
}
}
每次把context中的參數進行更新,保持你所擁有的用戶數據是真實值錢的。其中的rt字段為每次請求的目的(請求類型),它用來區分每次請求上來 我們需要調用那一台服務器的服務來處理請求。
服務架構和數據已經准備OK,我們接下來coding.
1:請求入口的承載類型選取
你是選擇傳統的.aspx頁面為入口還是ashx還是wcf/wcfRest/WebApi 這個自由度很大,具體在項目中的選擇主要看心情。我心情不好,所以選擇.aspx頁面。
主入口為Default.aspx頁面,代碼如下
1: protected void Page_Load(object sender, EventArgs e)
2: {
3: if(!IsPostBack)
4: {
5: try
6: {
7: }
8: catch (Exception exc)
9: {
10: }
11: }
12: }
在主入口處加一個大范圍的catch,而在catch中輸出系統忙。嗯,美其名曰:用戶體驗。
對json的壓縮我使用了GZip,代碼如下:
1: public static class CompressionHelper
2: {
3: /// <summary>
4: /// Compress the byte[]
5: /// </summary>
6: /// <param name="input"></param>
7: /// <returns></returns>
8: public static byte[] Compress(byte[] input)
9: {
10: byte[] output;
11: using (MemoryStream ms = new MemoryStream())
12: {
13: using (GZipStream gs = new GZipStream(ms, CompressionMode.Compress))
14: {
15: gs.Write(input, 0, input.Length);
16: gs.Close();
17: output = ms.ToArray();
18: }
19: ms.Close();
20: }
21: return output;
22: }
23:
24: /// <summary>
25: /// Decompress the byte[]
26: /// </summary>
27: /// <param name="input"></param>
28: /// <returns></returns>
29: public static byte[] Decompress(byte[] input)
30: {
31: List<byte> output = new List<byte>();
32: using (MemoryStream ms = new MemoryStream(input))
33: {
34: using (GZipStream gs = new GZipStream(ms, CompressionMode.Decompress))
35: {
36: int readByte = gs.ReadByte();
37: while (readByte != -1)
38: {
39: output.Add((byte)readByte);
40: readByte = gs.ReadByte();
41: }
42: gs.Close();
43: }
44: ms.Close();
45: }
46: return output.ToArray();
47: }
48: }
壓縮完json后,還需要加密,這個看你對數據的安全性如何看待。如支付寶用的RSACryptoServiceProvider加密,如asp.net的ViewState用的base64編碼。其實用什么編碼無所謂,你只需要定制屬於你自己的碼表。
接下來到重點了。你反序列化時可以使用Newtonsoft.json隨便得到了rt字段的類型。一般同學就開始這樣寫了:
1: switch (rt)
2: {
3: case"":
4: break;
5: default:
6: break;
7: }
這樣寫沒錯,但是如果你的rt類型比較多了以后就會出現很長很長的流水代碼。所以這個地方我更加建議動態,避免大串大串if else if。接下來就是具體的業務邏輯處理、數據處理。