HTML5 WebSocket Client使用详解

版权所有,禁止匿名转载;禁止商业使用。

最近因为有需要开发互动式网页,而且又需要频繁地和server端坐沟通,所以除了ajax之外,也开始研究一些新的东西;而其中一个,就是可以更节省频宽的WebSocket、这个HTML 5的通讯方法了~

关于WebSocket的介绍,建议庆直接参考维基百科,或是WebSocket.org的介绍;完整的API则可以参考W3C的网页。在Heresy来看,WebSocket和传统的HTML数据取得的方法相比,最大的好处,就是由于WebSocket是建立一个持续性的连线,不需要重复地不断建立连线,所以可以有效地降低延迟、并且减少数据的传输辆。
像右图就是WebSocket.org所提供的示意图,可以看到随着要求存取的次数的增加,传统的「Polling」的数据存取方法所需的频宽会上升地非常地快;相较之下,WebSocket的频宽则可以省非常地多。

另外,由于WebSocket在建立后,可以真正地由Server端主动送数据给client(浏览器),所以也可以避免掉一来一往之间的延迟。下方就是WebSocket.org的示意图:

而目前支援WebSocket的浏览器列表,可以参考:Can I Use这个网页或维基百科。基本上,主要的浏览器,只要版本够新,都是有支援的;比较大的问题,应该会是IE要到10.0才有支援,而Android内建的浏览器则完全没有支援。

WebSocket的Client端,一般就是使用JavaScript来做撰写,然后在浏览器内执行;他的基本使用也相当简单,在WebSocket.org的网站里,就有提供一个「Echo Test」的网页,算是可以做最基本的说明了~他的范例源代码如下(Heresy自己有略做修改):

<! DOCTYPE  html >   
< html >   
  < head >   
    < meta  charset = "utf-8"  />   
    < title > WebSocket Test </ title >   
       
    < script  language = "javascript"  type = "text/javascript" >   
      var wsUri = " ws:// echo.websocket.org /" ;  
       var output;  
 function init() {       
        
        output = document.getElementById( "output" );  
        testWebSocket();  
      }  
       
      function testWebSocket() {  
        websocket = new WebSocket(wsUri);  
        websocket.onopen = function (evt) {  
          onOpen(evt)  
        };  
       
        websocket.onclose = function (evt) {  
          onClose(evt)  
        };  
       
        websocket.onmessage = function (evt) {  
          onMessage(evt)  
        };  
       
        websocket.onerror = function (evt) {  
          onError(evt)  
        };  
      }  
       
      function onOpen(evt) {  
        writeToScreen( "CONNECTED" );  
        doSend( "WebSocket rocks" );  
      }  
       
      function onClose(evt) {  
        writeToScreen( "DISCONNECTED" );  
      }  
       
      function onMessage(evt) {  
        writeToScreen( '<span style="color:blue;">RESPONSE:' + evt.data + '</span>' );  
         websocket.close ();  
      }  
       
      function onError(evt) {  
        writeToScreen( '<span style="color:red;">ERROR:</span>' + evt.data );  
      }  
       
      function doSend(message) {  
        writeToScreen( "SENT: " + message);  
         websocket.send(message );  
      }  
       
      function writeToScreen(message) {  
         var pre = document.createElement( "p" );  
         pre.style.wordWrap = "break-word" ;  
        pre.innerHTML = message;  
        output.appendChild(pre);  
      }  
       
      window.addEventListener( "load" , init, false );  
 </ script > </ head > < body > < h2 > WebSocket Test </ h2 > < div id = "output" ></ div > </ body > < / html >

首先,在这个网页里面,HTML的部分相当简单,就是一个<H2>的标题,和一个id为「output」的<div>,用来做输出之用。而在网页载入完成后,他会去执行JavaScript的init()这个函数,开始进行WebSocket的测试。

实际上WebSocket测试的程序,是写在testWebSocket()这个函数里,它的使用方法相当单纯,首先就是要建立一个WebSocket的物件,也就是:
websocket = new WebSocket(wsUri);

在这边,传入的字串wsUri的内容是「ws:// echo.websocket.org /」,目的是告诉浏览器,这个WebSoscket是要连到哪里;在这边,就是连到WebSocket.org提供的测试Server。而这个URI前面的「ws://」,则是代表要使用WebSocket这种通讯协议,如果要使用加密的连线的话,则是要改成「wss://」。
后面的网址的部分,则也可以再加上连接埠、或是其他的路径,来当作进一步的数据;例如:「ws://localhost:12345/websocket/ server.php」也是一种合法的URI (参考)。

而之后,这个建立出来的websocket物件,会有四种事件,分别为:
onopen
当连线建立时,会被触??发的事件
onmessage
当收到Server 端发送的信息时,会被触??发的事件
onclose
连线中断时会被触发的事件
onerror
出现错误时会被触发的事件

这边基本上就是要针对这四种事件,来做设置,让程序可以在事件发生时,做对应的动作。像在上面的范例程序里,就是设置当这四种事件被触发的时候,会去调用对应的函数(例如,当onopen的事件触发的时候,就去调用onOpen()这个函数)。
而这个范例网页用浏览器打开后,基本上应该会看到下面的结果:
WebSocket Test

CONNECTED  
SENT: WebSocket rocks  
RESPONSE: WebSocket rocks/message  
DISCONNECTED

整个程序执行的流程,大致如下:

首先,当建立了一个WebSocket连线后,接下来通常都会是因为能正确地连线,所以会出发到onopen的事件,所以会去执行onOpen()这个函数;而这个函数所做的事,就是先输出一个「CONNECTED」的字串,然后再调用doSend()这个函数,送出「WebSocket rocks」这个字串。

而实际上,要通过WebSocket来送出信息,也相当简单,只要调用WebSocket物件(websocket)的send()这个函数就可以了~

接下来,Server端的部分,应该是设计成在收到client端送来的信息后,就原封不动地,把信息再送回给client端,所以接下来,这个网页就会因为收到Server端送来的信息,而触发到onmessage的事件,进而调用onMessage()这个函数。

而在这个范例程序里,在收到Server端送来的信息(evt)后,就会把他的数据(evt.data)作输出(上面蓝色的字),并且调用WebSocket的close()函数,把这个连线给关闭。

而由于连线被关闭了,所以接下来则是会触发到onclose的事件、进而执行onClose()这个函数;在这个函数里,基本上就是很简单地输出「DISCONNECTED」这个字串。
所以到上面为止,就是这个范例的基本概念了~基本上,他是在连线后、传递、接收一个信息后,马上就把连线断掉了;而如果再做修改,让他可以持续地送信息的话,就可以做到「echo test」这个范例网页里,可以持续传递、接收数据的功能了~而实际上,WebSocket的client端程序,大概也就是以这样的概念来写了。

另外,onmessage所收到的数据,实际上是一个MessageEvent的物件,它除了可以接收字串型别的数据外,其实也是可以接收Blob(参考)和ArrayBuffer(参考)这两种形式的数据,所以在技术上,其实WebSocket是可以用来传输相当复杂的东西的~


0 0