如何快速的開發一個完整的iOS直播app(搭建Web伺服器)

發表於2016-12-26

前言

在看這篇之前,如果您還不瞭解直播原理,請檢視這篇文章如何快速的開發一個完整的iOS直播app(原理篇)

在直播中,建立房間,獲取房間,都需要伺服器,因此需要搭建Web伺服器

Web伺服器

  • 能處理HTTP請求的伺服器都可以叫Web伺服器

Node.js介紹

  • Node.js什麼時候出現,2009年,Ryan Dahl(瑞恩·達爾)在GitHub上釋出了最初版本的部分Node.js包,隨後幾個月裡,有人開始使用Node.js開發應用
  • 什麼是Node.js,做過Javascript開發的,看到Node.js這個名字,初學者可能會誤以為這是一個Javascript應用,事實上,Node.js採用C++語言編寫而成,是一個Javascript的執行環境,意思就是底層使用c++編寫,外層封裝採用Javascript,需要使用Javascript解析執行。
  • 比如OC底層也是c++,但是執行程式碼,只需要解析OC程式碼。
  • Node.js是一個後端的Javascript執行環境,這意味著你可以編寫伺服器端的Javascript程式碼,交給Node.js來解釋執行。

Node.js工作原理與優缺點(瞭解一門語言的開始)

  • 傳統Web伺服器原理(T):傳統的網路服務技術,是每個新增一個連線(請求)便生成一個新的執行緒,這個新的執行緒會佔用系統記憶體,最終會佔掉所有的可用記憶體。
  • Node.js工作原理(T):只執行在一個單執行緒中,使用非阻塞的非同步 I/O 呼叫,所有連線都由該執行緒處理,也就是一個新的連線,不會開啟新的執行緒,僅僅一個執行緒去處理多個請求。
  • 優缺點
    • 傳統的比較消耗記憶體,Node.js只開啟一個執行緒,大大減少記憶體消耗。
    • 假設是普通的Web程式,新接入一個連線會佔用 2M 的記憶體,在有 8GB RAM的系統上執行時, 算上執行緒之間上下文切換的成本,併發連線的最大理論值則為 4000 個。這是在傳統 Web服務端技術下的處理情況。而 Node.js 則達到了約 1M 一個併發連線的擴充級別
    • Node.js弊端:大量的計算可能會使得 Node 的單執行緒暫時失去反應, 並導致所有的其他客戶端的請求一直阻塞, 直到計算結束才恢復正常
  • 疑問?Node.js是單執行緒的。單執行緒怎麼開啟非同步?怎麼工作的? 需要了解事件驅動。
  • 什麼是事件驅動?
  • 傳統的web server多為基於執行緒模型。你啟動Apache或者什麼server,它開始等待接受連線。當收到一個連線,server保持連線連通直到頁面或者什麼事務請求完成。如果他需要花幾微妙時間去讀取磁碟或者訪問資料庫,web server就阻塞了IO操作(這也被稱之為阻塞式IO).想提高這樣的web server的效能就只有啟動更多的server例項。
  • Node.Js使用事件驅動模型,當web server接收到請求,就把它關閉然後進行處理,然後去服務下一個web請求。當這個請求完成,它被放回處理佇列,當到達佇列開頭,這個結果被返回給使用者。這個模型非常高效可擴充套件性非常強,因為webserver一直接受請求而不等待任何讀寫操作。(這也被稱之為非阻塞式IO或者事件驅動IO)
  • 本質:當然最終處理事件還是需要底層開啟執行緒,只不過接受請求只用一個執行緒去接收。

Node.js使用介紹

  • Node.js使用Module模組去劃分不同的功能,以簡化App開發,Module就是庫,跟元件化差不多,一個功能一個庫。
  • NodeJS內建了一個HTTP伺服器,可以輕而易舉的實現一個網站和伺服器的組合,不像PHP那樣,在使用PHP的時候,必須先搭建一個Apache之類的HTTP伺服器,然後通過HTTP伺服器的模組載入CGI呼叫,才能將PHP指令碼的執行結果呈現給使用者
  • require() 函式,用於在當前模組中載入和使用其他模組;

Express模組(框架)

  • Express是Node.JS第三方庫
  • Express可以處理各種HTTP請求
  • Express是目前最流行的基於Node.js的Web開發框架,
  • Express框架建立在node.js內建的http模組上,可以快速地搭建一個Web伺服器
  • Express官方文件
  • Javascript文件

搭建Web伺服器步驟

一、安裝Node.JS

  • 開啟終端,輸入node -v,先檢視是否已經安裝
  • 如果沒有安裝,就需要安裝node軟體。
  • mac上可以使用Homebrew,安裝node
    • Homebrew:Homebrew簡稱brew,是Mac OSX上的軟體包管理工具,能在Mac中方便的安裝軟體或者解除安裝軟體,相當於window上360管家,可以幫你下載軟體。
  • 先輸入brew -v,檢視mac是否安裝了HomeBrew

  • 使用Homebrew安裝Node,輸入指令

  • 安裝完,輸入node -v檢視是否安裝成功

    二、安裝NPM

  • NPM是隨同NodeJS一起安裝的包管理工具,用於下載NodeJS第三方庫。
  • 類似iOS開發中cocoapods,用於安裝第三方框架
  • 新版的NodeJS已經整合了npm,所以只要安裝好Node.JS就好

三、利用NPM下載第三方模組(Express和Socket.IO)

  • package.json
    • package.json類似cocoapods中的Podfile檔案
    • package.json檔案描述了下載哪些第三方框架.
    • 可以使用npm init建立
    • 需要新增dependencies欄位,描述新增哪些框架,其他欄位隨便填
    • 注意:不能有中文符號

四、執行npm install,就會自動下載依賴庫

五、建立Node.JS檔案,搭建伺服器

  • 只要檔案,以js為字尾就可以了,比如app.js
  • 使用node app.js 就能執行檔案
  • 注意點:監聽埠要注意,不能使用已經佔用的埠比如(80),每個伺服器相當於一個app,都需要埠,才能找到入口

六、簡單的搭建Http伺服器

七、express框架

  1. 直接建立express應用,就是伺服器,可以直接監聽
  2. 需要主動監聽請求,get,post

八、路由

  1. 路由:如何響應客戶端的請求
  2. 新增url路徑,根據不同路徑,顯示不同內容
  3. 訪問地址,/home應該往埠後拼接,8080/home
  4. 路由控制程式碼(索引):執行完一個函式,接著執行下一個 ,因為有時候處理一個請求,需要做很多其他事情,寫在一起業務邏輯不好分開,所以多弄幾個行數

九、中介軟體

  1. 優化程式碼,使程式碼清晰可讀
  2. 注意點,函式一定要新增next引數,一定要呼叫next(),才會進行下面操作,程式碼使一行一行執行,解釋性語言
  3. 原理,傳送一個請求給伺服器的時候,會被中介軟體攔截,先由中介軟體處理,每個中介軟體都有一個回撥函式作為引數
  4. use是express註冊中介軟體的方法

  1. 程式碼演示

十、get請求引數

  1. request.query會把請求引數包裝成字典物件,直接通過點就能獲取引數

十一、post請求引數

  1. 使用http傳送請求,需要設定content-type欄位
  2. content-type欄位

    2.1 application/x-www-form-urlencoded(普通請求,預設一般使用這種)

    2.2 application/json(帶有json格式的引數,需要使用這個,比如引數是字典或者陣列)

    2.3 multipart/form-data(傳輸檔案,檔案上傳使用這個)

  3. AFN框架中AFHTTPRequestSerializer使用的是application/x-www-form-urlencoded,AFJSONRequestSerializer使用的是application/json
  4. Node.JS需要使用body-parser模組,解析post請求引數,安裝body-parser模組,用命令列

  1. 可以採用中介軟體的方式解析post請求引數

    5.1 注意bodyParser.urlencoded引數是一個字典,需要新增{}包裝,bodyParser.urlencoded({extends:true})
    5.2 extends必傳引數,是否展開

  1. 完整程式碼

十二、express建立物件返回客戶端

  • {}:字典 []:陣列
  • 自定義物件,才有function
  • function可以定義函式,也可以定義物件,一般有屬性的,都是物件
  • 定義物件,this:表示當前物件,類似self
  • 物件可以直接輸出

十三、express模組開發

  • 如果把所有程式碼寫在一個檔案中,不好維護,程式碼可讀性不好,最好分離檔案
  • 使用模組開發,exports用來定義模組介面,可以定義函式,也可以定義自定義物件,需要用module.exports
  • 注意,module.exports和exports不能重複,重複以module.exports為準
  • 路徑問題: ./ : 表示當前檔案
  • main.js

  • User.js

十四、字典和陣列刪除操作

  • 刪除陣列splice,splice有2兩個引數,第一個引數,從哪個角標開始 第二個引數,刪除幾個元素
  • 刪除字典delete
  • 注意:delete刪除陣列,刪除不乾淨,只是把元素刪除,當前角標位置並不會移除
    • [1,2,3] 比如delete arr[0] => [,2,3]

十四、直播房間伺服器搭建

  1. 建立package.json,安裝express模組
  2. 設計伺服器介面和客戶端怎麼互動
  3. 直播房間業務邏輯

    3.1 主播主動開啟房間

    3.2 通知伺服器開啟房間了
    3.3 伺服器儲存房間

    3.4 觀眾開啟房間,檢視直播

    3.5 主播關閉直播,通知伺服器移除房間號

  4. 伺服器處理

    4.1 主播開啟房間,建立房間,需要傳入給伺服器儲存

    4.2 伺服器用什麼儲存房間名稱,陣列還是字典

    4.3 應該使用字典儲存,當主播關閉房間時,可以根據房間號,找到伺服器對應的房間號刪除。

    4.4 新增房間,刪除房間之後,伺服器應該把最新的房間資訊返回給客戶端展示

    4.5 伺服器可以直接返回房間字典,但是這樣客戶端必須自己處理下,伺服器最好返回房間陣列

    4.6 Object.keys(rooms),傳入一個字典,就能獲取字典中所有keys,返回一個陣列

    4.7 然後遍歷keys陣列,一個一個取出對應的value,在儲存到陣列中

    4.8 可以使用map函式,讓陣列中所有元素執行一個方法,然後會自動把處理結果包裝成陣列.

    4.9 map函式原理,就是遍歷陣列中元素,一個一個執行,map函式的引數就是一個函式,,這個函式的引數就是陣列中的一個元素key,map需要有返回值,返回值就是key引數的處理結果,會自動把處理結果包裝到新陣列,然後再統一返回處理好的陣列

  5. 客戶端處理
    5.1 房間模型(ID,房間名稱)
    5.2 儲存到伺服器字典,ID作為Key,房間名稱作為Value
    5.3 在傳送伺服器的時候,需要把ID和Value傳給伺服器
    5.4 搞兩個引數(一個roomID,一個roomName)

伺服器程式碼

相關文章