欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

WebSocket實(shí)戰(zhàn)

系統(tǒng) 1888 0

前言

互聯(lián)網(wǎng)發(fā)展到現(xiàn)在,早已超越了原始的初衷,人類(lèi)從來(lái)沒(méi)有像現(xiàn)在這樣依賴過(guò)他;也正是這種依賴,促進(jìn)了互聯(lián)網(wǎng)技術(shù)的飛速發(fā)展。而終端設(shè)備的創(chuàng)新與發(fā)展,更加速了互聯(lián)網(wǎng)的進(jìn)化;

?

HTTP/1.1規(guī)范發(fā)布于1999年,同年12月24日,HTML4.01規(guī)范發(fā)布;盡管已到2012年,但HTML4.01仍是主流;雖然 HTML5的草案已出現(xiàn)了好幾個(gè)年頭,但轉(zhuǎn)正日期,遙遙無(wú)期,少則三五年,多則數(shù)十年;而HTML5的客戶代理(對(duì)于一般用戶而言,就是瀏覽器),則已百 家爭(zhēng)鳴,星星向榮;再加上移動(dòng)終端的飛速發(fā)展,在大多數(shù)情況下,我們都可以保證擁有一個(gè)HTML5的運(yùn)行環(huán)境,所以,我們來(lái)分享一下HTML5中的 WebSocket協(xié)議;

本文包含以下六個(gè)方面:
1. WebSocket的前世今生
2. WebSocket是什么
3. 為什么使用WebSocket
4. 搭建WebSocket服務(wù)器
5. WebSocket API
6. 實(shí)例解析

以上六點(diǎn)分為兩大塊,前3點(diǎn)側(cè)重理論,主要讓大家明白WebSocket是什么,而后3點(diǎn)則結(jié)合代碼實(shí)戰(zhàn),加深對(duì)WebSocket的認(rèn)知。

?

一、WebSocket的前世今生

Web 應(yīng)用的信息交互過(guò)程通常是客戶端通過(guò)瀏覽器發(fā)出一個(gè)請(qǐng)求,服務(wù)器端接收和審核完請(qǐng)求后進(jìn)行處理并返回結(jié)果給客戶端,然后客戶端瀏覽器將信息呈現(xiàn)出來(lái),這種 機(jī)制對(duì)于信息變化不是特別頻繁的應(yīng)用尚能相安無(wú)事,但是對(duì)于那些實(shí)時(shí)要求比較高的應(yīng)用來(lái)說(shuō)就顯得捉襟見(jiàn)肘了。我們需要一種高效節(jié)能的雙向通信機(jī)制來(lái)保證數(shù) 據(jù)的實(shí)時(shí)傳輸。有web TCP之稱(chēng)的WebSocket應(yīng)運(yùn)而生,給開(kāi)發(fā)人員提供了一把強(qiáng)有力的武器來(lái)解決疑難雜癥。
(PS:其實(shí),在早期的HTML5規(guī)范中,并沒(méi)有包含WebSocket的定義,一些早期的HTML5書(shū)籍中,完全沒(méi)有WebSocket的介紹。直到后來(lái),才加入到當(dāng)前的草案中。)

?

二、WebSocket是什么?

其實(shí),從背景介紹中,我們大致的可以猜出,WebSocket是干什么用的。前面我們提到,WebSocket有web TCP之稱(chēng),既然是TCP,肯定是用來(lái)做通信的,但是它又有不同的地方,WebSocket作為HTML5中新增的一種通信協(xié)議,由通信協(xié)議和編程API 組成,它能夠在瀏覽器和服務(wù)器之間建立雙向連接,以基于事件的方式,賦予瀏覽器原生的實(shí)時(shí)通信能力,來(lái)擴(kuò)展我們的web應(yīng)用,增加用戶體驗(yàn),提升應(yīng)用的性 能。何謂雙向?服務(wù)器端和客戶端可以同時(shí)發(fā)送并響應(yīng)請(qǐng)求,而不再像HTTP的請(qǐng)求和響應(yīng)。

?

三、為什么使用WebSocket

在WebSocket出現(xiàn)之前,我們有一些其它的實(shí)時(shí)通訊方案,比較常用的有輪詢,長(zhǎng)輪詢,流,還有基于Flash的交換數(shù)據(jù)的方式,接下來(lái),我們一一分析一下,各種通信方式的特點(diǎn)。

?

① 輪詢
這是最早的一種實(shí)現(xiàn)實(shí)時(shí)web應(yīng)用的方案;原理比較簡(jiǎn)單易懂,就是客戶端以一定的時(shí)間間隔向服務(wù)器發(fā)送請(qǐng)求,以頻繁請(qǐng)求的方式來(lái)保持客戶端和服務(wù)器端的數(shù) 據(jù)同步。但是問(wèn)題也很明顯:當(dāng)客戶端以固定頻率向服務(wù)器端發(fā)送請(qǐng)求時(shí),服務(wù)器端的數(shù)據(jù)可能并沒(méi)有更新,這樣會(huì)帶來(lái)很多無(wú)謂的請(qǐng)求,浪費(fèi)帶寬,效率低下。

?

② 長(zhǎng)輪詢
長(zhǎng)輪詢是對(duì)定時(shí)輪詢的改進(jìn)和提高,目地是為了降低無(wú)效的網(wǎng)絡(luò)傳輸。當(dāng)服務(wù)器端沒(méi)有數(shù)據(jù)更新的時(shí)候,連接會(huì)保持一段時(shí)間周期直到數(shù)據(jù)或狀態(tài)改變或者時(shí)間過(guò) 期,通過(guò)這種機(jī)制來(lái)減少無(wú)效的客戶端和服務(wù)器間的交互。當(dāng)然,如果服務(wù)端的數(shù)據(jù)變更非常頻繁的話,這種機(jī)制和定時(shí)輪詢比較起來(lái)沒(méi)有本質(zhì)上的性能的提高。

?

③ 流
長(zhǎng)輪詢是對(duì)定時(shí)輪詢的改進(jìn)和提高,目地是為了降低無(wú)效的網(wǎng)絡(luò)傳輸。當(dāng)服務(wù)器端沒(méi)有數(shù)據(jù)更新的時(shí)候,連接會(huì)保持一段時(shí)間周期直到數(shù)據(jù)或狀態(tài)改變或者時(shí)間過(guò) 期,通過(guò)這種機(jī)制來(lái)減少無(wú)效的客戶端和服務(wù)器間的交互。當(dāng)然,如果服務(wù)端的數(shù)據(jù)變更非常頻繁的話,這種機(jī)制和定時(shí)輪詢比較起來(lái)沒(méi)有本質(zhì)上的性能的提高。

?

④ 基于Flash的實(shí)時(shí)通訊方式
Flash有自己的socket實(shí)現(xiàn),這為實(shí)時(shí)通信提供了可能。我們可以利用Flash完成數(shù)據(jù)交換,再利用Flash暴露出相應(yīng)的接口,方便 JavaScript調(diào)用,來(lái)達(dá)到實(shí)時(shí)傳輸數(shù)據(jù)的目的。這種方式比前面三種方式都要高效,而且應(yīng)用場(chǎng)景比較廣泛;因?yàn)閒lash本身的安裝率很高;但是在 當(dāng)前的互聯(lián)網(wǎng)環(huán)境下,移動(dòng)終端對(duì)flash的支持并不好,以IOS為主的系統(tǒng)中根本沒(méi)有flash的存在,而在android陣營(yíng)中,雖然有flash的 支持,但實(shí)際的使用效果差強(qiáng)人意,即使是配置較高的移動(dòng)設(shè)備,也很難讓人滿意。就在前幾天(2012年6月底),Adobe官方宣布,不在支持 android4.1以后的系統(tǒng),這基本上宣告了flash在移動(dòng)終端上的死亡。

下面是輪詢和長(zhǎng)輪詢的信息流轉(zhuǎn)圖:
WebSocket實(shí)戰(zhàn)
WebSocket實(shí)戰(zhàn)

對(duì)比完四種不同的實(shí)時(shí)通信方式,不難發(fā)現(xiàn),除了基于flash的方案外,其它三種方式都是用AJAX方式來(lái)模擬實(shí)時(shí)的效果,每次客戶端和服務(wù)器端交 互時(shí),都是一次完整的HTTP請(qǐng)求和應(yīng)答的過(guò)程,而每一次的HTTP請(qǐng)求和應(yīng)答都帶有完整的HTTP頭信息,這就增加每次的數(shù)據(jù)傳輸量,而且這些方案中客 戶端和服務(wù)端的編程實(shí)現(xiàn)比較復(fù)雜。

?

接下來(lái),我們?cè)賮?lái)看一下WebSocket,為什么要使用它呢?高效節(jié)能,簡(jiǎn)單易用。
下圖是來(lái)自websocket.org的測(cè)試結(jié)果:
WebSocket實(shí)戰(zhàn)

在流量和負(fù)載增大的情況下,WebSocket 方案相比傳統(tǒng)的 Ajax 輪詢方案有極大的性能優(yōu)勢(shì);而在開(kāi)發(fā)方面,也十分簡(jiǎn)單,我們只需要實(shí)例化WebSocket,創(chuàng)建連接,查看是否連接成功,然后就可以發(fā)送和相應(yīng)消息了。我們會(huì)在后面的實(shí)例中去詳細(xì)的說(shuō)明API。

?

四、搭建WebSocket服務(wù)器

其實(shí),在服務(wù)器的選擇上很廣,基本上,主流語(yǔ)言都有WebSocket的服務(wù)器端實(shí)現(xiàn),而我們作為前端開(kāi)發(fā)工程師,當(dāng)然要選擇現(xiàn)在比較火熱的NodeJS作為我們的服務(wù)器端環(huán)境了。

?

NodeJS本身并沒(méi)有原生的WebSocket支持,但是有第三方的實(shí)現(xiàn)(大家要是有興趣的話,完全可以參考WebSocket協(xié)議來(lái)做自己的實(shí)現(xiàn)),我們選擇了“ws”作為我們的服務(wù)器端實(shí)現(xiàn)。

?

由于本文的重點(diǎn)是講解WebSocket,所以,對(duì)于NodeJS不做過(guò)多的介紹,不太熟悉的朋友可以去參考NodeJS入門(mén)指南(http://www.nodebeginner.org/index-zh-cn.html)。

?

安裝好NodeJS之后,我們需要安裝“ws”,也就是我們的WebSocket實(shí)現(xiàn),安裝方法很簡(jiǎn)單,在終端或者命令行中輸入:

      npm install ws
    
,等待安裝完成就可以了。

接下來(lái),我們需要啟動(dòng)我們的WebSocket服務(wù)。首先,我們需要構(gòu)建自己的HTTP服務(wù)器,在NodeJS中構(gòu)建一個(gè)簡(jiǎn)單的HTTP服務(wù)器很簡(jiǎn)單,so easy。代碼如下:

      var app = http.createServer( onRequest ).listen( 8888 );
    
?

onRequest()作為回調(diào)函數(shù),它的作用是處理請(qǐng)求,然后做出響應(yīng),實(shí)際上就是根據(jù)接收的URL,在服務(wù)器上查找相應(yīng)的資源,最終返回給瀏覽器。
在構(gòu)建了HTTP服務(wù)器后,我們需要啟動(dòng)WebSocket服務(wù),代碼如下:

      var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer( { server : app } );
    
?

從代碼中可以看出,在初始化WebSocket服務(wù)時(shí),把我們剛才構(gòu)建好的HTTP實(shí)例傳遞進(jìn)去就好。到這里,我們的服務(wù)端代碼差不多也就編寫(xiě)完成了。怎么樣?很簡(jiǎn)單吧。

?

五、WebSocket API

上面我們介紹了WebSocket服務(wù)端的知識(shí),接下來(lái),我們需要編寫(xiě)客戶端代碼了。在前面我們說(shuō)過(guò),客戶端的API也是一如既往的簡(jiǎn)單:
WebSocket實(shí)戰(zhàn)
見(jiàn)上圖:ready state中定義的是socket的狀態(tài),分為connection、open、closing和closed四種狀態(tài),從字面上就可以區(qū)分出它們所代表的狀態(tài)。

WebSocket實(shí)戰(zhàn)
上圖描述的是WebSocket的事件,分為onopen、onerror和onclose;

WebSocket實(shí)戰(zhàn)
上圖為消息的定義,主要是接收和發(fā)送消息。注意:可以發(fā)送二進(jìn)制的數(shù)據(jù)。

?

以上個(gè)圖的具體的含義就不再一一贅述,詳細(xì)描述請(qǐng)參考:
http://www.w3.org/TR/2012/WD-websockets-20120524/


PS:由于WebSocket API(截止到2012年7月)還是草案,API文檔和上文所描述的會(huì)有所不同,請(qǐng)以官方文檔為主,這也是我為什么不詳細(xì)描述API中各個(gè)屬性的原因。

?

另外一點(diǎn)需要提醒大家的是:在前端開(kāi)發(fā)中,瀏覽器兼容是必不可少的,而WebSocket在主瀏覽器中的兼容還是不錯(cuò)的,火狐和Chrome不用 說(shuō),最新版的支持非常不錯(cuò),而且支持二進(jìn)制數(shù)據(jù)的發(fā)送和接收。但是IE9并不支持,對(duì)于國(guó)內(nèi)的大多數(shù)應(yīng)用場(chǎng)景,WebSocket無(wú)法大規(guī)模使用。

WebSocket實(shí)戰(zhàn) 截 圖來(lái)自(http://tongji.baidu.com/data/browser),之所以選擇百度的統(tǒng)計(jì)數(shù)據(jù),是因?yàn)楦臃蠂?guó)內(nèi)的實(shí)際情況。圖中 所展示的是2012年4月1日到2012年6月30日之間的統(tǒng)計(jì)數(shù)據(jù),從圖中不難看出IE6.0、奇虎360、IE7.0和IE8.0加起來(lái)一共占據(jù)了 77%的市場(chǎng),F(xiàn)ireFox屬于其他,chrome只有5.72%的份額,再一次告訴我們,我們的主戰(zhàn)場(chǎng)依然是IE系。

?

既然是IE系,那么對(duì)于WebSocket在實(shí)際app中的應(yīng)用就基本不可能了。但我們完全可以在chrome、FireFox、以及移動(dòng)版的IOS瀏覽器中使用它。

?

六、實(shí)例解析

搭建好了服務(wù)端,熟悉了API,接下來(lái),我們要開(kāi)始構(gòu)建我們的應(yīng)用了。鑒于WebSocket自身的特點(diǎn),我們的第一個(gè)demo選擇了比較常見(jiàn)的聊天程序,我們暫且取名為chat。

?

說(shuō)到聊天,大家最先想到的肯定是QQ,沒(méi)錯(cuò),我們所實(shí)現(xiàn)的應(yīng)用和QQ類(lèi)似,而且還是基于web的。因?yàn)槭莇emo,我們的功能比較簡(jiǎn)陋,僅實(shí)現(xiàn)了最 簡(jiǎn)單的會(huì)話功能。就是啟動(dòng)WebSocket服務(wù)器后,客戶端發(fā)起連接,連接成功后,任意客戶端發(fā)送消息,都會(huì)被服務(wù)器廣播給所有已連接的客戶端,包括自己。

?

既然需要客戶端,我們需要構(gòu)建一個(gè)簡(jiǎn)單的html頁(yè)面,頁(yè)面中樣式和元素,大家可以自由發(fā)揮,只要能夠輸入消息,有發(fā)送按鈕,最后有一個(gè)展示消息的區(qū)域即可。具體的樣子大家可以看附件中的demo。

?

寫(xiě)玩HTML頁(yè)面之后,我們需要添加客戶端腳本,也就是和WebSocket相關(guān)的代碼;前面我們說(shuō)過(guò),WebSocket的API本身很簡(jiǎn)單,所以,我們的客戶端代碼也很直接,如下:

      var wsServer = 'ws://localhost:8888/';
var websocket = new WebSocket(wsServer);
websocket.binaryType = "arraybuffer";
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
websocket.onerror = onError;
    
?
?

首先,我們需要指定WebSocket的服務(wù)地址,也就是var wsServer = ‘ws://localhost:8888/’;

然后,我們實(shí)例化WebSocket,new WebSocket(wsServer),
剩下的就是指定相應(yīng)的回調(diào)函數(shù)了,分別是onOpen,onClose,onMessage和onError,對(duì)于咱們的實(shí)驗(yàn)應(yīng)用來(lái)說(shuō),onopen、onclose、onerror甚至可以不管,咱們重點(diǎn)關(guān)注一下onmessage。

onmessage()這個(gè)回調(diào)函數(shù)會(huì)在客戶端收到消息時(shí)觸發(fā),也就是說(shuō),只要服務(wù)器端發(fā)送了消息,我們就可以通過(guò)onmessage拿到發(fā)送的數(shù)據(jù),既然拿到了數(shù)據(jù),接下去該怎么玩,就隨便我們了。請(qǐng)看下面的偽代碼:

1 function onMessage(evt) {
2 ???? var json = JSON.parse(evt.data);
3 ???? commands[json.event](json.data);
4 }

因?yàn)閛nmessage只接收字符串和二進(jìn)制類(lèi)型的數(shù)據(jù),如果需要發(fā)送json格式的數(shù)據(jù),就需要我們轉(zhuǎn)換一下格式,把字符串轉(zhuǎn)換成JSON格式。 只要是支持WebSocket,肯定原生支持window.JSON,所以,我們可以直接使用JSON.parse()和 JSON.stringify()來(lái)進(jìn)行轉(zhuǎn)換。
轉(zhuǎn)換完成后,我們就得到了我們想要的數(shù)據(jù)了,接下來(lái)所做的工作就是將消息顯示出來(lái)。實(shí)際上就是

1 Elements.innerHTML += data + '</br>';

上面展現(xiàn)了客戶端的代碼,服務(wù)器端的代碼相對(duì)要簡(jiǎn)單一些,因?yàn)槲覀兊姆?wù)器端使用的是第三方實(shí)現(xiàn),我們只需要做一些初始化工作,然后在接收到消息時(shí),將消息廣播出去即可,下面是具體的代碼:

01 var app = http.createServer( onRequest ).listen( 8888 );
02 var WebSocketServer = require('ws').Server,
03 ???? wss = new WebSocketServer( { server : app } );
04 wss.on('connection', function( ws ) {
05 ???? console.log('connection successful!');
06 ???? ws.on('message', function( data, flags ) {
07 ???????? console.log(data);
08 ???????? //do something here
09 ???? });
10 ???? ws.on('close', function() {
11 ???????? console.log('stopping client');
12 ???? });
13 });

我們可以通過(guò)wss.clients獲得當(dāng)前已連接的所有客戶端,然后遍歷,得到實(shí)例,調(diào)用send()方法發(fā)送數(shù)據(jù);

1 var clients = wss.clients, len = clients.length, i = 0;
2 ???????? for( ; i < len; i = i + 1 ){
3 ???????????? clients[i].send( msg );
4 ???????? }

說(shuō)到這里,一個(gè)雙向通信的實(shí)例基本完成,當(dāng)然,上面都是偽代碼,完整的demo請(qǐng)查看附件。

除了常見(jiàn)的聊天程序以外,大家完全可以發(fā)揮創(chuàng)意,構(gòu)建一些“好玩”的應(yīng)用;
接下來(lái),分享另外一個(gè)應(yīng)用,“你畫(huà)我猜”這個(gè)應(yīng)用,很多人都接觸過(guò),大致上是:某個(gè)人在屏幕上畫(huà)一些圖形,這些圖片會(huì)實(shí)時(shí)展示在其它人的屏幕上,然后來(lái)猜畫(huà)的是什么。

利用WebSocket和canvas,我們可以很輕松的構(gòu)建類(lèi)似的應(yīng)用。當(dāng)然,我們這里只是demo,并沒(méi)有達(dá)到產(chǎn)品級(jí)的高度,這里只是為大家提供思路;
首先,我們?cè)俅蚊鞔_一下,WebSocket賦予了我們?cè)跒g覽器端和服務(wù)器進(jìn)行雙向通信的能力,這樣,我們可以實(shí)時(shí)的將數(shù)據(jù)發(fā)送給服務(wù)器,然后再?gòu)V播給所有的客戶端。這和聊天程序的思路是一致的。

接下來(lái),服務(wù)器端的代碼不用做任何修改,在html頁(yè)面中準(zhǔn)備一個(gè)canvas,作為我們的畫(huà)布。如何在canvas上用鼠標(biāo)畫(huà)圖形呢?我們需要監(jiān) 聽(tīng)mousedown、mousemove和mouseup三個(gè)鼠標(biāo)事件。說(shuō)到這里,大家應(yīng)該知道怎么做了。沒(méi)錯(cuò),就是在按下鼠標(biāo)的時(shí)候,記錄當(dāng)前的坐 標(biāo),移動(dòng)鼠標(biāo)的時(shí)候,把坐標(biāo)發(fā)送給服務(wù)器,再由服務(wù)器把坐標(biāo)數(shù)據(jù)廣播給所有的客戶端,這樣就可以在所有的客戶端上同步繪畫(huà)了;最后,mouseup的時(shí) 候,做一些清理工作就ok了。下面是一些偽代碼:

01 var WhiteBoard = function( socket, canvasId ){
02 ???????????????? var lastPoint = null,
03 ???????????????????? mouseDown = false,
04 ???????????????????? canvas = getById(canvasId),
05 ???????????????????? ctx = canvas.getContext('2d');
06 ?
07 ???????????????? var handleMouseDown = function(event) {
08 ???????????????????? mouseDown = true;
09 ???????????????????? lastPoint = resolveMousePosition.bind( canvas, event )();
10 ???????????????? };
11 ?
12 ???????????????? var handleMouseUp = function(event) {
13 ???????????????????? mouseDown = false;
14 ???????????????????? lastPoint = null;
15 ???????????????? };
16 ?
17 ???????????????? var handleMouseMove = function(event) {
18 ???????????????????? if (!mouseDown) { return; }
19 ???????????????????? var currentPoint = resolveMousePosition.bind( canvas, event )();
20 ???????????????????? socket.send(JSON.stringify({
21 ???????????????????????? event: 'draw',
22 ???????????????????????? data: {
23 ???????????????????????????? points: [
24 ???????????????????????????????? lastPoint.x,
25 ???????????????????????????????? lastPoint.y,
26 ???????????????????????????????? currentPoint.x,
27 ???????????????????????????????? currentPoint.y
28 ???????????????????????????? ]
29 ???????????????????????? }
30 ???????????????????? }));
31 ?
32 ???????????????????? lastPoint = currentPoint;
33 ???????????????? };?????????
34 ?
35 ???????????????? var init = function(){
36 ???????????????????? addEvent( canvas, 'mousedown', handleMouseDown );
37 ???????????????????? addEvent( canvas, 'mouseup', handleMouseUp );
38 ???????????????????? addEvent( canvas, 'mousemove', handleMouseMove );
39 ?
40 ???????????????????? var img = new Image();
41 ???????????????????? addEvent( img, 'load', function(e){
42 ???????????????????????? canvas.width = img.width;
43 ???????????????????????? canvas.height = img.height;
44 ???????????????????????? ctx.drawImage( img, 0, 0 );
45 ???????????????????? } );
46 ???????????????????? img.src = '/img/diablo3.png';
47 ???????????????? };
48 ?
49 ???????????????? var drawLine = function(data) {
50 ???????????????????? var points = data.points;
51 ???????????????????? ctx.strokeStyle = 'rgb(255, 15, 255)';
52 ???????????????????? ctx.beginPath();
53 ???????????????????? ctx.moveTo( points[0] + 0.5, points[1] + 0.5 );
54 ???????????????????? ctx.lineTo( points[2] + 0.5, points[3] + 0.5 );
55 ???????????????????? ctx.stroke();
56 ???????????????? };
57 ?
58 ???????????????? function resolveMousePosition(event) {
59 ???????????????????? var x, y;
60 ???????????????????? if (event.offsetX) {
61 ???????????????????????? x = event.offsetX;
62 ???????????????????????? y = event.offsetY;
63 ???????????????????? } else {? //(注意)實(shí)際開(kāi)發(fā)中,這樣獲取鼠標(biāo)相對(duì)canvas的坐標(biāo)是不對(duì)的
64 ???????????????????????? x = event.layerX - this.offsetLeft;
65 ???????????????????????? y = event.layerY - this.offsetTop;
66 ???????????????????? }
67 ???????????????????? return { x: x, y: y };
68 ???????????????? };
69 ?
70 ???????????????? init();
71 ?
72 ???????????????? return {
73 ???????????????????? draw : drawLine
74 ???????????????????? //ctx : ctx,
75 ???????????????????? //canvas : canvas
76 ???????????????? }
77 ???????????? }( websocket, 'drawsomething' );

對(duì)于canvas不熟悉的同學(xué),請(qǐng)自己去搜索一下,有許多不錯(cuò)的教程。其它方面,和聊天應(yīng)用的思路基本一樣。

最后,我們需要明確一點(diǎn),WebSocket本身的優(yōu)點(diǎn)很明顯,但是作為一個(gè)正在演變中的web規(guī)范,我們必須清楚的認(rèn)識(shí)到WebSocket在構(gòu) 建應(yīng)用時(shí)的一些風(fēng)險(xiǎn);雖然本身有很多局限性,但是這項(xiàng)技術(shù)本身肯定是大勢(shì)所趨,WebSocket在移動(dòng)終端,在chrome web store都有用武之地,我們可以進(jìn)行大膽的嘗試,讓我們?cè)诩夹g(shù)的革新中不被淘汰。

Resources:
http://www.w3.org/TR/websockets/
W3 API的官方文檔,有詳細(xì)的接口設(shè)計(jì)文檔和實(shí)現(xiàn)步驟
http://tools.ietf.org/html/rfc6455
WebSocket協(xié)議
http://tools.ietf.org/html/rfc6202
Known Issues and Best Practices for the Use of Long Polling and Streaming in Bidirectional HTTP
http://msdn.microsoft.com/en-us/library/ie/hh673567(v=vs.85).aspx
msdn中關(guān)于WebSocket的介紹
https://developer.mozilla.org/en/WebSockets
http://caniuse.com/#feat=websockets
Compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.

?

原文: ? WebSocket實(shí)戰(zhàn) by Ji Yunpeng / 前端開(kāi)發(fā)

?

?

?

WebSocket實(shí)戰(zhàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 一区中文 | 在线91 | 欧美精品午夜久久久伊人 | 99精品国产福利在线观看 | 一级片网址 | 黄色午夜电影 | 亚洲精品一区二区三区在线看 | 色老头久久网 | 美女在线视频网站 | 久久精品亚洲欧美日韩精品中文字幕 | 91视频无限看 | 亚洲一区色 | 国产午夜精品视频免费不卡69堂 | 一级片视频免费观看 | 国产精品久久久久久吹潮 | 三级在线观看 | 国产AV一区二区三区传媒 | 精品自拍视频 | 天堂国产 | 免费国产一区 | 极品xxxx欧美一区二区 | 一区二区三区欧美 | 亚洲91| 欧美成人免费看片一区 | 99一区二区三区 | 国产成人精品一区二区三区四区 | 99精品久久秒播无毒不卡 | 牛和人交videos欧美冫3d | 免费观看日本a毛片 | 色偷偷噜噜噜亚洲男人 | 精品国产一区二区三区久久久蜜臀 | 香蕉久草视频 | 国内精品久久久久久中文字幕 | 成人黄色在线 | 中文字幕一区二区三区四区 | 啪啪乐视频 | 青娱分类视频精品免费2 | 成人不卡在线 | jdav视频在线观看免费 | 97婷婷狠狠成人免费视频 | 久久久噜噜噜久久中文字幕色伊伊 |