HTML 5之中一个很酷的新特性就是Web Sockets,在本文之前51CTO在《HTML 5 Web Socket:下一次Web通信革命揭幕》一文中已经详细的为大家介绍过HTML 5 Web Sockets为Web通信带来的改变,而本文将介绍通过PHP环境的服务器端运行Web Socket,创建客户端并通过Web Sockets协议发送和接收服务器端信息。
什么是Web Sockets?
Web Sockets是在一个(TCP)接口进行双向通信的技术,PUSH技术类型。同时Web Sockets仍将基于W3C标准,目前为止,Chrome和Safari的最新版本浏览器已经支持Web Sockets了。
Web Sockets将会替代什么?
Web Sockets可以替代Long Polling(PHP服务端推送技术),这是一个有趣的概念。客户端发送一个请求到服务器,现在,服务器端并不会响应还没准备好的数据,它会保持连接的打开状态直到最新的数据准备就绪发送,之后客户端收到数据,然后发送另一个请求。
这有它的好处:减少任一连接的延迟,当一个连接已经打开时就不需要创建另一个新的连接。但是Long-Polling并不是什么花俏技术,他仍有可能发生请求暂停,因此会需要建立新的连接。
一些Ajax应用使用上述技术-这经常是归因于低资源利用。试想一下,如果服务器在早晨会自启动并发送数据到那些希望接收而不用提前建立一些连接端口的客户端,这是一件多棒的事情啊!欢迎来到PUSH技术的世界!
第一步:搞定Web Socket服务器
文章会把更多的精力放在客户端的创建而不是服务器端的执行等操作。作者使用的是基于Windows 7的XAMPP来实现本地运行PHP。
启动Apache服务器
第二步:修改URLs和端口
根据你之前的安装修改服务器,下面是setup.class.php中的例子:
- public function __construct($host='localhost',$port=8000,$max=100)
- $this->createSocket($host,$port);
浏览文件并在适当情况下进行更改。
第三步:开始创建客户端
下面来创建基本模板,这是我的client.php文件:
- <!DOCTYPE html>
- <html>
- <head>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- <title>Web Sockets Client</title>
- </head>
- <body>
- <div id="wrapper">
- <div id="container">
- <h1>Web Sockets Client</h1>
- <div id="chatLog">
- </div><!-- #chatLog -->
- <p id="examples">e.g. try 'hi', 'name', 'age', 'today'</p>
- <input id="text" type="text" />
- <button id="disconnect">Disconnect</button>
- </div><!-- #container -->
- </div>
- </body>
- </html>
我们已经创建里基本模板:一个chat log容器,一个input输入框和一个断开连接的按钮。
第四步:添加一些CSS
没什么花俏代码,只是处理一下标签的样式。
- body {
- font-family:Arial, Helvetica, sans-serif;
- }
- #container{
- border:5px solid grey;
- width:800px;
- margin:0 auto;
- padding:10px;
- }
- #chatLog{
- padding:5px;
- border:1px solid black;
- }
- #chatLog p {
- margin:0;
- }
- .event {
- color:#999;
- }
- .warning{
- font-weight:bold;
- color:#CCC;
- }
第五步:Web Socket事件
首先让我们尝试并理解Web Socket事件的概念:
◆onopen: 当接口打开时
◆onmessage: 当收到信息时
◆onclose: 当接口关闭时
我们如何来实现呢?首先创建Web Socket对象。
- var socket = new Web Socket("ws://localhost:8000/socket/server/startDaemon.php");
然后向下面这样检测事件:
- socket.onopen = function(){
- alert("Socket has been opened!");
- }
当我们收到信息时这样做:
- socket.onmessage = function(msg){
- alert(msg); //Awesome!
- }
但我们还是尽量避免使用alert,现在我们可以把我们学的东西整合到客户端页面中了。
第六步:JavaScript
首先我们将代码放到jQuery 的 document.ready函数中,然后我们还要检查用户的浏览器是否支持Web Socket。如果不支持,我们就添加一个链向Chrome浏览器页面的链接。
- $(document).ready(function() {
- if(!("Web Socket" in window)){
- $('#chatLog, input, button, #examples').fadeOut("fast");
- $('<p>Oh no, you need a browser that supports Web Sockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
- }else{
- //The user has Web Sockets
- connect();
- function connect(){
- //the connect function code is below
- }
- });
如你所见,如果用户浏览器支持Web Socket,我们将执行connect()函数。这里是核心功能,我们将开始创建open、close和receive事件。我们将在我们的服务器定义URL。
- var socket;
- var host = "ws://localhost:8000/socket/server/startDaemon.php";
你可能会发现URL中怎么没有http?恩,是的,这是一个Web Socket URL,使用了不同的协议。下面是URL分解图示:
下面让我们继续完成connect()函数,我们将代码放入try/catch块,这样如果代码出现问题,我们能让用户知道。我们创建Web Socket,并将信息传递到message()函数,之后会做讲解。我们创建我们的onopen、onmessage和onclose函数. 需要注意的是我们为用户提供了端口状态,这并不是必需的,但我们把它放进来主要是为了方便调试。
- CONNECTING = 0
- OPEN = 1
- CLOSED = 2
- function connect(){
- try{
- var socket;
- var host = "ws://localhost:8000/socket/server/startDaemon.php";
- var socket = new Web Socket(host);
- message('<p class="event">Socket Status: '+socket.readyState);
- socket.onopen = function(){
- message('<p class="event">Socket Status: '+socket.readyState+' (open)');
- }
- socket.onmessage = function(msg){
- message('<p class="message">Received: '+msg.data);
- }
- socket.onclose = function(){
- message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
- }
- } catch(exception){
- message('<p>Error'+exception);
- }
- }
message()函数很简单, 它将我们想展现给用户的文本填入chat log容器内。 我们在socket事件函数中为段落(<p>)标签创建适当的class,我们在message函数中只有一个段落结束标签。
- function message(msg){
- $('#chatLog').append(msg+'</p>');
- }
目前的成果
如果你已按上面教程按部就班的做的话,很好,我们已经创建了HTML/CSS模板、创建并建立Web Socket连接、通过创建连接保持用户的进展更新。
第七步:发送数据
现在我们已经有了提交按钮,但我们还需要监听用户按下键盘的事件,并运行send函数,下面的’13′便是回车键对应的ASCII码。
- $('#text').keypress(function(event) {
- if (event.keyCode == '13') {
- send();
- }
- });
下面是send()函数:
- function send(){
- var text = $('#text').val();
- if(text==""){
- message('<p class="warning">Please enter a message');
- return ;
- }
- try{
- socket.send(text);
- message('<p class="event">Sent: '+text)
- } catch(exception){
- message('<p class="warning"> Error:' + exception);
- }
- $('#text').val("");
下面我们需要:
- socket.send();
那些额外的代码做了以下工作:检测用户是否什么都没输入却仍点击返回、清空input输入框、执行message()函数。
第八步:关闭Socket
关闭Socket操作相当简单,添加对断开连接按钮的click事件监听就可以。
- $('#disconnect').click(function(){
- socket.close();
- });
完整JavaScript代码
- $(document).ready(function() {
- if(!("Web Socket" in window)){
- $('#chatLog, input, button, #examples').fadeOut("fast");
- $('<p>Oh no, you need a browser that supports Web Sockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
- }else{
- //The user has Web Sockets
- connect();
- function connect(){
- var socket;
- var host = "ws://localhost:8000/socket/server/startDaemon.php";
- try{
- var socket = new Web Socket(host);
- message('<p class="event">Socket Status: '+socket.readyState);
- socket.onopen = function(){
- message('<p class="event">Socket Status: '+socket.readyState+' (open)');
- }
- socket.onmessage = function(msg){
- message('<p class="message">Received: '+msg.data);
- }
- socket.onclose = function(){
- message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
- }
- } catch(exception){
- message('<p>Error'+exception);
- }
- function send(){
- var text = $('#text').val();
- if(text==""){
- message('<p class="warning">Please enter a message');
- return ;
- }
- try{
- socket.send(text);
- message('<p class="event">Sent: '+text)
- } catch(exception){
- message('<p class="warning">');
- }
- $('#text').val("");
- }
- function message(msg){
- $('#chatLog').append(msg+'</p>');
- }
- $('#text').keypress(function(event) {
- if (event.keyCode == '13') {
- send();
- }
- });
- $('#disconnect').click(function(){
- socket.close();
- });
- }//End connect
- }//End else
- });
第九步:运行Web Socket服务器
我们要输入一些命令行,XAMPP提供了比较方便的shell选项。点击XAMPP控制面板的’shell’按钮并输入:
- php -q path\to\server.php
现在你已经运行了Web Socket服务器!
大功告成!
当页面读取后,将尝试创建一个Web Socket连接,然后用户可以输入信息并从服务器接收信息。大家可以通过The Web Socket API了解HTML 5 Web Socket的最新动态。