前言: 話說前陣子爸爸家陽台不斷出現米奇老鼠,立刻清理陽台所有東西,然後又跟市政部門反映問題,可是情況還沒有好轉,米老鼠來完一隻又一隻,我爸陽台在老鼠界應該是網紅打卡聖地(誤),要不然就是米奇老鼠版米奇林三星餐廳(?) 雖然我們抓到了三隻,到上兩個禮拜為止還有至少一隻一直抓不到,每天淩晨還會來吃事後煙留下老鼠屎,真_北。 這隻老鼠對傳統攻擊有抗性,有IT9朋友前陣子用Raspberry pi自製了一台electric mouse trap ,用pi的超聲波雷達放在鞋盒裡,鞋盒裡有一堆食物,底部佈了鐵網,偵測到有老鼠進去以後立即關門通9V電,通個1分鐘再放牠離開,大推我自己也造一台 (Youtube片搜尋一大堆,人類真變態啊,朋友好變態啊)。可是我覺得這樣又好像有點太殘忍,不如先偵測牠們什麼時候來,嚇嚇牠們看看有沒有效果再說吧。 目的: 用Raspberry pi及手上有的感測器弄一隻放陽台用來偵測和嚇嚇老鼠的東西,並把紀錄圖像化到雲端給老爸使用。 邏輯及設計: 當老鼠進入偵測範圍,Motion Sensor偵測到生物活動Raspberry pi 處理來自Motion Sensor的訊號,如果夠強的話開始準備作出回應 Raspberry pi在Angry cats sounds中隨機選出叫聲,再經由Speaker輸出貓叫聲 Raspberry pi指示強光元件發出強光束照射目標 把偵測計數上傳到雲端圖表 材料: Sensor 在網路上看了一些Raspberry pi wild animal camera ,很多也是用Motion Sensor先偵測動物再來,我用的是PIR Motion Sensor被動式紅外線感測器,有低耗電成本便宜的好處。[1],而且可手動調整靈敏度及反應時間。 PIR Motion Sensor就是下面這個 圖片來源: learn.adafruit.com 可手動調整敏感度還有反應時間,這個有點不好調,要試好多遍才找到最佳位置。 可以在Raspbian中輸入pinout查詢GPIO避免插錯 圖片來源: learn.adafruit.com . 一台Raspberry pi 這次使用較舊的Raspberry pi model B+ 萬一老鼠生氣被咬爛錢包也不太痛 . 一張
研究背景:
最近協助朋友研究在公司網站建立新功能,讓客戶可以直接上傳檔案到公司的內部伺服器。
系統架構如下圖,檔案最後會放在公司內部的Web API Servr。而Web API接收上傳檔案的API是使用HTML的FormData格式
小弟後來試過自己產生multi-part/formdata,可是實在有點麻煩所以放棄了。
最近協助朋友研究在公司網站建立新功能,讓客戶可以直接上傳檔案到公司的內部伺服器。
系統架構如下圖,檔案最後會放在公司內部的Web API Servr。而Web API接收上傳檔案的API是使用HTML的FormData格式
問題:
- 網路上大部分教學是利用jquery ajax把檔案直接上傳到Web API上,可是公司Web API是內部使用的伺服器,所以只能透過Web Server存取。
解決方案:
以下是其中一種試過可行的做法。
- Web Server部分
- Web API接收上傳檔案的API是使用HTML的FormData格式,所以當Web Server接收到Browser的上傳後需要把檔案轉成multipart/form-data的http Request,然後發送到後端的Web API去。產生的方法至少有兩種
- 自己寫HTTP Request Message
post Upload上传文件中multipart/form-data 做的那些事 - 使用套件 RESTSharp
Git - 我們所使用的是REST Sharp。先讀取來自Browser的Request,然後把檔案變成multipart/form-data,再產生Http Request上傳到Web API。
namespace /*project name*/.Controllers { public class FilesController : Controller { // GET: Files public string Upload() { List<string> filesList = new List<string>(); try { foreach(string file in Request.Files) { var fileContent = Request.Files[file]; if (fileContent != null & fileContent.ContentLength > 0) { // get a stream var stream = fileContent.InputStream; RestRequest request = new RestRequest("resource/{id}", Method.POST); request.AddFile("fileData", ReadToEnd(stream), null); request.AddHeader("Content-Type", "multipart/form-data"); request.AlwaysMultipartFormData = true; /*密碼跟username刪除掉*/ /**/ /**/ RestClient client = new RestClient(/*Web API的位置*/); IRestResponse restResponse = client.Execute(request); /*自己定義的回傳訊息, 等於HttpReponseMessage*/ myRespModel responseMsg = JsonConvert.DeserializeObject<myRespModel>(restResponse.Content); if (responseMsg.OK ) { string fm ; /*把Web API回傳的亂數檔案名稱用Json格式回傳到Browser*/ fm = JsonConvert.DeserializeObject<IEnumerable<string>>(responseMsg.Message).FirstOrDefault(); filesList.Add(fm); } else { throw new Exception(); } } } } catch { filesList = null; } /*把Web API回傳的亂數檔案名稱回傳到Browser*/ return JsonConvert.SerializeObject(filesList); } /*讀取檔案*/ public byte[] ReadToEnd(Stream stream) { long originalPosition = stream.Position; stream.Position = 0; try { byte[] readBuffer = new byte[4096]; /*最大上傳檔案size*/ int totalBytesRead = 0; int bytesRead; while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) { totalBytesRead += bytesRead; if (totalBytesRead == readBuffer.Length) { int nextByte = stream.ReadByte(); if (nextByte != -1) { byte[] temp = new byte[readBuffer.Length * 2]; Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); readBuffer = temp; totalBytesRead++; } } } byte[] buffer = readBuffer; if (readBuffer.Length != totalBytesRead) { buffer = new byte[totalBytesRead]; Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); } return buffer; } finally { stream.Position = originalPosition; } } } }
- Browser的部分
- html的部分
<input type="file" name="UploadFiles" id="UploadFiles" multiple />
<input name="HiddenUploadFiles" id="HiddenUploadFiles" type="hidden" value
hidden field是用來接收從Web Server回傳回來的亂數檔案名稱- Javascript的部分
$('#UploadFiles').on('change', function (e) { var files = e.target.files; if (window.FormData !== undefined) { var data = new FormData(); for (var x = 0; x < files.length; x++) { data.append("file" + x, files[x]); } $.ajax({ type: "POST", url: 'WebServer位置/Files/Upload', contentType: false, processData: false, data: data, success: function (result) { dataType: 'application/json; charset=utf-8', $('#HiddenUploadFiles').val(result); }, error: console.log('err'); } }); } else { alert("不支援"); } })
總結:
Web API和Web Service最大的差異是Web API大量使用Http協定,所以習慣寫web service的人像我經常會搞混兩種做法。
Comments
Post a Comment