More Related Content
Similar to 使用Javascript及HTML5打造協同運作系統 (20)
使用Javascript及HTML5打造協同運作系統
- 2. 自介
●
渾名: fillano
●
工作:就是個卑微的 web 工程師
●
喜歡 Javascript
●
出沒:
– Plurk 、 Facebook 、 G+ 、 iTHelp 等
- 3. 緣起
●
參加 2012 年的 iTHelp 鐵人賽,不知道要做
什麼 ...
●
報名截止的最後一天,趕鴨子上架時才想到
這樣的主題
●
不過其實也只是把之前嘗試過的技術做一個
整合應用
●
但是實作過程也還蠻有趣的
- 4. 協同運作系統?
●
其實只是這個名詞聽起來比較專業 ... 骨子
裡就是聊天室、白板、資源共享、視訊會議
等應用的組合
●
不過因為是多人同時使用,在實作的過程
中,還會碰到一些資料同步的邏輯問題
●
另外,基於興趣與需求,一些東西就自己刻
了
- 5. 幾個技術範疇
● Websocket
● Canvas 2D Context
● WebRTC
● AMD
● Bootstrap
- 6. 幾個應用主題
●
聊天室 (websocket)
●
多人共享白板 (canvas+websocket)
●
資源共享 (websocket)
●
視訊會議 (WebRTC)
●
將應用整合在一起
– 實作 AMD
– 利用 Bootstrap 把不同應用整合在同一個 UI
- 7. 訊息流通的基礎: websocket
●
在實作這些應用時,使用 websocket 作為訊息
傳送的基本機制
●
Client / Server 的程式,則透過 Socket.IO 這個
framework 來實作
- 8. Socket.IO
● http://socket.io
●
是 node.js 上最常用來做聊天室等訊息推送應用
的框架(幾乎也是最早的)
●
利用他可以把各種訊息交換抽象成事件,然後透
過在 client 端觸發 server 事件、在 server 端觸發
client 事件的方式來運作
●
雖然使用方式看起來很像 websocket ,實際上 ...
(容後再敘)
- 9. Socket.IO 的 server 程式像這樣
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
- 10. Socket.IO 的 client 端程式像這樣
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
- 11. 聊天室的邏輯
●
用兩個事件就可以做出聊天室
– 在 client 用 socket.on('client event',
function(){}) 定義 client 事件,用來更新頁
面上顯示的聊天訊息
– 在 server 用 socket.on('server event',
function(){}) 定義 server 事件,用來轉發
訊息
- 12. 聊天室的邏輯
●
在 client 用 socket.emit('server event', data)
就可以觸發 server 事件,把聊天訊息送到
server 的事件處理器
●
在 server 用 socket.emit('client event', data)
則可以觸發 client 事件,把收到的聊天訊息
轉發給 client 顯示
●
群發的話,就用 socket.broadcast.emit()
- 13. 聊天室的簡單展示
● node test830.js
●
下載:
https://dl.dropbox.com/u/7949788/test830.zip
●
執行前需安裝 node.js, npm, socket.io, redis
- 14. 進階聊天室
●
實用的聊天室,需要區分出 room ,讓加入的人選
擇要進入想要進入的聊天室
●
Socket.IO 利用三個 fluent 的函數來支援這樣的功能
●
socket.join('room') 加入某個 room
●
socket.leave('room') 離開某個 room
●
socket.broadcast.in('room').emit() 對個 room 群發
訊息
- 15. 進階聊天室邏輯
●
系統可以用些方式定義可以使用的聊天室來
供使用者選擇
●
當選擇聊天室時,會先 leave 前一個聊天
室,然後 join 要進入的聊天室
- 16. 進階聊天室展示
● node test843.js
●
下載:
https://dl.dropbox.com/u/7949788/test843.zip
●
執行前需安裝: node.js, npm, ws.io
●
( 課中展示的程式有問題,我後來在使用
ws.io 的版本修改過 )
- 18. 共享白板的設計構想
●
為了可以共享,必須定義出個別的繪圖功
能,他可以接收 context 與資料作為參數,
然後把圖形繪製出來
●
這樣設計,才能用 websocket 廣播要指定的
繪圖功能,傳送繪圖的資料,讓所有的
client 同時繪製出一致的圖形
- 19. 共享白板的設計構想
●
為了讓系統可以有彈性的擴充繪圖功能,使
用 template method 模式來設計
– 繪圖功能的流程統一,並且有一致的方法
– 利用註冊的方式把繪圖功能加入系統
– 系統使用一致的方式調用繪圖功能的方法,
把繪圖結果呈現
- 20. 白板的特殊需求
●
所視即所得
– 最初只使用一個 Canvas ,顯示即時繪製的
效果與最終的結果
– 但是這樣在「共享」時會出現問題:例如用
滑鼠拖拉出一個矩形,同時處理其他人繪
製結果,會出亂子
– 所以使用兩個 Canvas 來實作,一個做所視
即所得,另一個繪製結果
- 21. 共享白板的簡單展示
● node test842.js
●
下載:
https://dl.dropbox.com/u/7949788/test842.zip
●
執行前需安裝: node.js, npm, ws.io
- 22. 資源共享
●
這裡說的資源,其實是指檔案
●
為了測試一下 websocket 最終規格中的
binary 資料傳送,這部份使用 websocket 、
File API 及 URL 來實作
●
不過呢, Socket.IO 似乎沒支援 binary 資料
(blob, Typed Array 等 ) 傳送,所以自己刻一
個用起來跟 Socket.IO 很像的東西,管他叫
ws.io
- 23. 實際上什麼是 Socket.IO?
●
他其實是一套協定,實際傳輸方法可以切
換,並不限定是 websocket
●
這個協定定義了資料的格式以及 url 的
pattern ,利用這些標準來實作出底層的機
制( session, namespace 等)
●
不過他的可以傳送的資料格式就只有字串 ...
- 24. 那麼什麼是 ws.io?
●
包裝 ws 這個支援 binary 資料傳輸的
websocket 模組 (Socket.IO 底層也用這個 )
●
實作跟 Socket.IO 類似的語法,包含事件定
義與觸發、群發、 room 、 store 等
●
調整底層資料格式,讓他可以透過
websocket 傳送 binary 資料
- 25. 資源共享的邏輯
●
透過 input[type=file] 來選擇檔案
●
透過 FileAPI 取得檔案的 Blob 資料以及檔
名、 MIME 等資訊
●
透過 ws.io 將這些資料群發給共享的對象
●
透過 URL.createObjectURL() 處理收到的
Blob ,將他轉成可操作的超連結
- 26. 資源共享的簡單展示
● node test844.js
●
下載:
https://dl.dropbox.com/u/7949788/test844.zip
●
執行前需安裝: node.js, npm, ws.io
- 27. 視訊會議
●
這部份基本上會用到幾個技術
– WebRTC 的 getUserMedia
– WebRTC 的 RTCPeerConnection
– URL.createObjectURL
– Video 元素
– websocket
- 28. 視訊會議的邏輯
●
發起方把初始的連線資訊丟給接收方
●
接收方把初始的連線資訊丟回給發起方
●
透過 STUN/TURN server 偵測連線方式
●
不斷交換資訊並嘗試連線
●
成功連線 / 連線失敗
●
把視訊串流附加到連線上
- 29. 視訊會議的簡單展示
● node test851.js
●
下載:
https://dl.dropbox.com/u/7949788/test851.zip
●
執行前需安裝: node.js, npm, ws.io
●
支援瀏覽器: Chrome 23
●
程式邏輯只支援兩個 peer
- 30. 不過呢 ...
●
WebRTC 的規格一直調整
●
所以完賽後這部份的 demo 就不能動了 XD
●
所以 ... 剛剛展示的是會後改的
- 31. 整合
●
為了讓 client 以可以支援模組,參考 AMD
的規格實作了一個簡單的模組系統
●
使用 Bootstrap 快速建立美觀的 UI
- 32. 什麼是 AMD?
●
他是 async module definition 的縮寫,讓你
在 browser 也可以使用模組系統
●
定義模組: define('name', ['dep1','dep2'...],
function(dep1, dep2) {return {/*module
object*/};})
●
使用模組: require(['dep1','dep2'],
function(dep1, dep2){/*code uses the
modules*/})
- 33. AMD 的實作邏輯
●
內建一個簡單的 cache ,以 module path 作
為 key
●
呼叫 define 時,把模組物件存入 cache
●
呼叫 require 時,如果 cache 中存在依賴的
模組物件就直接使用,否則就用動態產生
script tag 的方式載入
- 34. 實作 AMD 的困難點
●
需要根據定義的依賴關係來載入模組,最後
把模組當做參數傳給 require 中的 callback
●
模組載入的方式是非同步的,控制流程的方
法需要花一些腦力來設計
- 35. 雖然自己做了 AMD...
●
不過實際上這是自 high 的東西,而且功能
還頗受限
●
用在產品上的話,使用 require.js 還比較實
際 XD
●
下載:
https://dl.dropbox.com/u/7949788/amd.js
- 36. 套上 Bootstrap
●
利用他的「分頁」,來把不同功能放在不同
的分頁
●
利用他的 sprite 圖示,來美化一些按鈕(不
過呢 ... )
- 37. 套上 Bootstrap 後的樣子
● node test848.js
●
下載:
https://dl.dropbox.com/u/7949788/test848.zip
●
(尚未完成,程式還無法執行,只能看到外
觀)
- 38. 缺少的東西
●
符合實務需求的流程
●
身分認證
● UI Design
- 39. 未來展望
●
Chrome 在下個版本會實驗性支援 TURN
●
Chromey 在下下個版本會支援
DataChannel
- 40. 參考
● http://ithelp.ithome.com.tw/ironman5/player/fillano
● http://tools.ietf.org/html/rfc6455
● http://www.w3.org/TR/websockets/
● http://www.w3.org/TR/2dcontext/
● http://www.webrtc.org/
● http://www.w3.org/TR/webrtc/
● http://www.w3.org/TR/FileAPI/