SlideShare a Scribd company logo
1 of 41
Download to read offline
用 Javascript 及 HTML5 打造協同
           運作系統



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

More Related Content

What's hot

Koa 正在等一個人
Koa 正在等一個人Koa 正在等一個人
Koa 正在等一個人Fred Chien
 
ASP.NET MVC 6 新功能探索
ASP.NET MVC 6 新功能探索ASP.NET MVC 6 新功能探索
ASP.NET MVC 6 新功能探索Will Huang
 
Node.js 淺談socket.io
Node.js   淺談socket.ioNode.js   淺談socket.io
Node.js 淺談socket.ioSimon Su
 
Node.js從無到有 基本課程
Node.js從無到有 基本課程Node.js從無到有 基本課程
Node.js從無到有 基本課程Simon Su
 
SignalR實戰技巧 twmvc#17
SignalR實戰技巧 twmvc#17 SignalR實戰技巧 twmvc#17
SignalR實戰技巧 twmvc#17 twMVC
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Joseph Chiang
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事Ben Lue
 
Non-MVC Web Framework
Non-MVC Web FrameworkNon-MVC Web Framework
Non-MVC Web FrameworkFred Chien
 
twMVC#36讓 Exceptionless 存管你的 Log
twMVC#36讓 Exceptionless 存管你的 LogtwMVC#36讓 Exceptionless 存管你的 Log
twMVC#36讓 Exceptionless 存管你的 LogtwMVC
 
如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12twMVC
 
TypeScript-twmvc#16
TypeScript-twmvc#16TypeScript-twmvc#16
TypeScript-twmvc#16twMVC
 
Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2twMVC
 
用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式Fred Chien
 
twMVC#36.NetCore 3快速看一波
twMVC#36.NetCore 3快速看一波twMVC#36.NetCore 3快速看一波
twMVC#36.NetCore 3快速看一波twMVC
 
Node.js 進攻桌面開發
Node.js 進攻桌面開發Node.js 進攻桌面開發
Node.js 進攻桌面開發Fred Chien
 
專案分層架構 twMVC#18
專案分層架構 twMVC#18專案分層架構 twMVC#18
專案分層架構 twMVC#18twMVC
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC
 
Getting started with test automation
Getting started with test automationGetting started with test automation
Getting started with test automationIvan Wei
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具taobao.com
 

What's hot (19)

Koa 正在等一個人
Koa 正在等一個人Koa 正在等一個人
Koa 正在等一個人
 
ASP.NET MVC 6 新功能探索
ASP.NET MVC 6 新功能探索ASP.NET MVC 6 新功能探索
ASP.NET MVC 6 新功能探索
 
Node.js 淺談socket.io
Node.js   淺談socket.ioNode.js   淺談socket.io
Node.js 淺談socket.io
 
Node.js從無到有 基本課程
Node.js從無到有 基本課程Node.js從無到有 基本課程
Node.js從無到有 基本課程
 
SignalR實戰技巧 twmvc#17
SignalR實戰技巧 twmvc#17 SignalR實戰技巧 twmvc#17
SignalR實戰技巧 twmvc#17
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
Non-MVC Web Framework
Non-MVC Web FrameworkNon-MVC Web Framework
Non-MVC Web Framework
 
twMVC#36讓 Exceptionless 存管你的 Log
twMVC#36讓 Exceptionless 存管你的 LogtwMVC#36讓 Exceptionless 存管你的 Log
twMVC#36讓 Exceptionless 存管你的 Log
 
如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12
 
TypeScript-twmvc#16
TypeScript-twmvc#16TypeScript-twmvc#16
TypeScript-twmvc#16
 
Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2
 
用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式用最潮的 Java script 盡情開發 kde qt 程式
用最潮的 Java script 盡情開發 kde qt 程式
 
twMVC#36.NetCore 3快速看一波
twMVC#36.NetCore 3快速看一波twMVC#36.NetCore 3快速看一波
twMVC#36.NetCore 3快速看一波
 
Node.js 進攻桌面開發
Node.js 進攻桌面開發Node.js 進攻桌面開發
Node.js 進攻桌面開發
 
專案分層架構 twMVC#18
專案分層架構 twMVC#18專案分層架構 twMVC#18
專案分層架構 twMVC#18
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure Functions
 
Getting started with test automation
Getting started with test automationGetting started with test automation
Getting started with test automation
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具
 

Similar to 使用Javascript及HTML5打造協同運作系統

July.2011.w3ctech
July.2011.w3ctechJuly.2011.w3ctech
July.2011.w3ctechKai Cui
 
twMVC#42 讓我們用一種方式來開發吧
twMVC#42 讓我們用一種方式來開發吧twMVC#42 讓我們用一種方式來開發吧
twMVC#42 讓我們用一種方式來開發吧twMVC
 
twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC
 
Axure RP Prototyping Tool
Axure RP Prototyping ToolAxure RP Prototyping Tool
Axure RP Prototyping ToolSouyi Yang
 
Responsive Web UI Design
Responsive Web UI DesignResponsive Web UI Design
Responsive Web UI Designjay li
 
轻量级Flash服务器开发框架(刘恒)
轻量级Flash服务器开发框架(刘恒)轻量级Flash服务器开发框架(刘恒)
轻量级Flash服务器开发框架(刘恒)FLASH开发者交流会
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境Will Huang
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发leneli
 
初探 Elastic Observability 的實踐方法
初探 Elastic Observability 的實踐方法初探 Elastic Observability 的實踐方法
初探 Elastic Observability 的實踐方法Joe Wu
 
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)
Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)Joseph Kuo
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsChieh Lin
 
Kissy design
Kissy designKissy design
Kissy designyiming he
 
20120516 axure rp prototype design outline
20120516 axure rp prototype design outline20120516 axure rp prototype design outline
20120516 axure rp prototype design outlineturtleknight
 
Noder eyes for frontend guys
Noder eyes for frontend guysNoder eyes for frontend guys
Noder eyes for frontend guysHsu Ping Feng
 
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)Will Huang
 
React.js what do you really mean?
React.js what do you really mean?React.js what do you really mean?
React.js what do you really mean?昱安 周
 
玩轉 .NET Interactive Notebooks 一次就上手
玩轉 .NET Interactive Notebooks 一次就上手玩轉 .NET Interactive Notebooks 一次就上手
玩轉 .NET Interactive Notebooks 一次就上手Poy Chang
 
这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkitLainZQ
 

Similar to 使用Javascript及HTML5打造協同運作系統 (20)

Html5
Html5Html5
Html5
 
July.2011.w3ctech
July.2011.w3ctechJuly.2011.w3ctech
July.2011.w3ctech
 
twMVC#42 讓我們用一種方式來開發吧
twMVC#42 讓我們用一種方式來開發吧twMVC#42 讓我們用一種方式來開發吧
twMVC#42 讓我們用一種方式來開發吧
 
twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有
 
Axure RP Prototyping Tool
Axure RP Prototyping ToolAxure RP Prototyping Tool
Axure RP Prototyping Tool
 
Responsive Web UI Design
Responsive Web UI DesignResponsive Web UI Design
Responsive Web UI Design
 
轻量级Flash服务器开发框架(刘恒)
轻量级Flash服务器开发框架(刘恒)轻量级Flash服务器开发框架(刘恒)
轻量级Flash服务器开发框架(刘恒)
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
 
Berserk js
Berserk jsBerserk js
Berserk js
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发
 
初探 Elastic Observability 的實踐方法
初探 Elastic Observability 的實踐方法初探 Elastic Observability 的實踐方法
初探 Elastic Observability 的實踐方法
 
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)
Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development Fundamentals
 
Kissy design
Kissy designKissy design
Kissy design
 
20120516 axure rp prototype design outline
20120516 axure rp prototype design outline20120516 axure rp prototype design outline
20120516 axure rp prototype design outline
 
Noder eyes for frontend guys
Noder eyes for frontend guysNoder eyes for frontend guys
Noder eyes for frontend guys
 
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)
使用 C#/Razor 開發互動式 WebAssembly 網站 (Modern Web 2018)
 
React.js what do you really mean?
React.js what do you really mean?React.js what do you really mean?
React.js what do you really mean?
 
玩轉 .NET Interactive Notebooks 一次就上手
玩轉 .NET Interactive Notebooks 一次就上手玩轉 .NET Interactive Notebooks 一次就上手
玩轉 .NET Interactive Notebooks 一次就上手
 
这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit
 

使用Javascript及HTML5打造協同運作系統

  • 1. 用 Javascript 及 HTML5 打造協同 運作系統 By Fillano
  • 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 的版本修改過 )
  • 17. 共享白板 共享白板簡單說就是兩個 HTML5 功能的組合 ● 使用 canvas 來實作繪圖功能 ● 使用 websocket 來傳送共享的繪圖資料
  • 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/
  • 41. Q&A