
HTML5之中一个很酷的新特性就是WebSockets,它可以让我们无需AJAX请求即可与服务器端对话。今天彬Go将让大家通过Php环境的服务器端运行WebSocket,创建客户端并通过WebSockets协议发送和接收服务器端信息。
您还可以参考以下HTML5相关文章:
《关于HTML 5 canvas 的基础教程》
《让所有IE支持HTML5的解决方案》
《一起感受HTML5和CSS3的能量》
什么是WebSockets?
WebSockets是在一个(TCP)接口进行双向通信的技术,PUSH技术类型。同时WebSockets仍将基于W3C标准,目前为止,Chrome和Safari的最新版本浏览器已经支持WebSockets了。
WebSockets将会替代什么?
WebSockets可以替代Long Polling(PHP服务端推送技术),这是一个有趣的概念。客户端发送一个请求到服务器,现在,服务器端并不会响应还没准备好的数据,它会保持连接的打开状态直到最新的数据准备就绪发送,之后客户端收到数据,然后发送另一个请求。这有它的好处:减少任一连接的延迟,当一个连接已经打开时就不需要创建另一个新的连接。但是Long-Polling并不是什么花俏技术,他仍有可能发生请求暂停,因此会需要建立新的连接。
一些AJAX应用使用上述技术-这经常是归因于低资源利用。
试想一下,如果服务器在早晨会自启动并发送数据到那些希望接收而不用提前建立一些连接端口的客户端,这是一件多棒的事情啊!欢迎来到PUSH技术的世界!
第一步:搞定WebSocket服务器
这篇教程会把更多的精力放在客户端的创建而不是服务器端的执行等操作。
我使用基于windows 7的XAMPP来实现本地运行PHP。phpwebsockets是PHP WebSocket服务器。(以我的经验这个版本存在一些小问题,我已对它做了些修改并上传源文件共享给大家)下面的这些不同版本也可以实现WebSocket,如果某个不能用,你可以试试其它版本或者继续看下面的教程。
jWebSocket (Java)
web-socket-ruby (ruby)
Socket IO-node (node.js)
启动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>WebSockets Client</title>
</head>
<body>
<div id="wrapper">
<div id="container">
<h1>WebSockets 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;
}
第五步:WebSocket事件
首先让我们尝试并理解WebSocket事件的概念:

WebSocket事件:
我们将使用三个WebSocket事件:
onopen: 当接口打开时
onmessage: 当收到信息时
onclose: 当接口关闭时
我们如何来实现呢?
首先创建WebSocket对象
var socket = new WebSocket("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函数中,然后我们还要检查用户的浏览器是否支持WebSocket。如果不支持,我们就添加一个链向Chrome浏览器页面的链接。
$(document).ready(function() {
if(!("WebSocket" in window)){
$('#chatLog, input, button, #examples').fadeOut("fast");
$('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
}else{
//The user has WebSockets
connect();
function connect(){
//the connect function code is below
}
});
如你所见,如果用户浏览器支持WebSocket,我们将执行connect()函数。这里是核心功能,我们将开始创建open、close和receive事件。
我们将在我们的服务器定义URL。
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
你可能会发现URL中怎么没有http?恩,是的,这是一个WebSocket URL,使用了不同的协议。下面是URL分解图示:

下面让我们继续完成connect()函数,我们将代码放入try/catch块,这样如果代码出现问题,我们能让用户知道。我们创建WebSocket,并将信息传递到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 WebSocket(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 模板、创建并建立Websocket连接、通过创建连接保持用户的进展更新。

第七步:发送数据
现在我们已经有了提交按钮,但我们还需要监听用户按下键盘的事件,并运行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("");
}
下面我们需要:
那些额外的代码做了以下工作:检测用户是否什么都没输入却仍点击返回、清空input输入框、执行message()函数。
关闭Socket
关闭Socket操作相当简单,添加对断开连接按钮的click事件监听就可以。
$('#disconnect').click(function(){
socket.close();
});

$(document).ready(function() {
if(!("WebSocket" in window)){
$('#chatLog, input, button, #examples').fadeOut("fast");
$('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
}else{
//The user has WebSockets
connect();
function connect(){
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
try{
var socket = new WebSocket(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
});
第九步:运行WebSocket服务器
我们要输入一些命令行,XAMPP提供了比较方便的shell选项。点击XAMPP控制面板的’shell’按钮并输入:
php -q path\to\server.php
现在你已经运行了WebSocket服务器!

大功告成!
当页面读取后,将尝试创建一个WebSocket连接,然后用户可以输入信息并从服务器接收信息。

感谢大家耐心阅读本教程,希望你能从中学到有用的知识,HTML5 WebSocket的确令人兴奋不已!大家可以通过The WebSocket API了解HTML5 WebSocket的最新动态。
点击这里下载源文件
留意更新
订阅彬Go以查看HTML5最新资源、教程。
英文原文:Start Using HTML5 WebSockets Today
翻译原文:HTML5 WebSockets 基础使用教程(彬Go)
31 条 关于 "HTML5 WebSockets 基础使用教程" 的评论
mark,
确实很让人兴奋。
HTML5不光让前设计更简洁方便,更让程序等后端更深入浅出了。
更新频率低了。怎想今天来了居然还没占到沙发。悲剧。
在不支持websocket的浏览器使用flashsocket解决
http://github.com/gimite/web-socket-js
[...] This post was mentioned on Twitter by iVane Hwang, kiven. kiven said: RT @ivane: HTML5 WebSockets 基础使用教程 http://is.gd/eaOKP 【之前发过英文版的,现在终于有中文版的了~】 [...]
mark~
问下
php不会
jsp可以做这个不?
期待html5…….
aspx.net
可以吗?
试过了,不成功啊,握手之后再发送的时候没有反应..
相当不错的网站。学习学习,不知道咋回事。我邮箱今天订阅不了。怪!
对html一窍不通啊~
说错了 是html5
Thanks for all the nice thinks here at the site.
帅哥,偶最近在学习您的代码~~
使用的是 wamp 集成环境
为啥握手以后 我在页面中的状态 始终为0
教程很不错,多谢博主分享
[...] Using HTML5 WebSockets Today 翻译原文:HTML5 WebSockets 基础使用教程(彬Go) 转载声明: [...]
有了websockets后,ajax还有什么意义么?
请问,port您程式是用8000,是因为XAMPP预设port是8000吗? 如果别的架站包预设port不是8000,是否就要改成为8000 ?
Hi 彬Go,我把server和client程序放在web server上,把代码里的localhost改为对应ip,在chrome里运行以后,netstat命令可以看到server和client已经在8000端口上建立了tcp连接,但是在客户端chrome里只显示“Socket Status: 0”,没有显示socket状态1,在输入框里输入文字以后在显示栏里也没有任何显示,不知道是哪里的问题?
[...] 翻译原文:HTML5 WebSockets 基础使用教程 [...]
dfgb fgb
这个示例代码有错误,没有处理握手时的hash值,所以可以连接,但客户端无法响应onopen事件。
兄弟,我刚刚架上去了,可是send不了消息啊,握手是成功了,但是,就是send不出去消息,不知道是为什么啊,希望给个回复给大家!谢谢!
用上面的代码,发送不成功,跟踪了一下错误。
socket.send(text);
总是发生这样的异常,why?
Error: INVALID_STATE_ERR: DOM Exception 11
浏览器:chrome10
我把代码运行了一下报错,请问一下为什么会找不到函数?
Fatal error: Call to undefined function socket_create() in D:\ProgramFiles\Apache\htdocs\socket\server\socket.class.php on line 38
cwwap不支持websocket~
好东西 就是这方面的资料太少了啊
试了下,用Chrome连接时发送的头信息格式不正确,总是连接失败。
而在Safari可以成功。
Chrome的版本时14.0.835.163
服务器是web-socket-ruby (ruby)
Chrome的header是:
{
“sec-websocket-version”=>”8″,
“connection”=>”Upgrade”,
“Sec-WebSocket-Version”=>”8″,
“cookie”=>”_tumblr_cn_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRiIlNGU0NGFlYmUyNGM4YTA4YTEwZjRiMDIwMTEwOWFmY2NJIhBfY3NyZl90b2tlbgY7AEZJIjFLLyt0WWZ4N1ZONFZSTmJmRmpKYzJQT1hHU05xZVVuQ3JTY0szT1FZWEw0PQY7AEY%3D–cffa0022a6c42da633ca6159f2847ed6f8df648a”,
“Cookie”=>”_tumblr_cn_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRiIlNGU0NGFlYmUyNGM4YTA4YTEwZjRiMDIwMTEwOWFmY2NJIhBfY3NyZl90b2tlbgY7AEZJIjFLLyt0WWZ4N1ZONFZSTmJmRmpKYzJQT1hHU05xZVVuQ3JTY0szT1FZWEw0PQY7AEY%3D–cffa0022a6c42da633ca6159f2847ed6f8df648a”,
“Upgrade”=>”websocket”,
“sec-websocket-key”=>”CtRXwwluDmRDdDUVvFpV9Q==”,
“host”=>”localhost:10081″,
“Sec-WebSocket-Key”=>”CtRXwwluDmRDdDUVvFpV9Q==”,
“sec-websocket-origin”=>”http://127.0.0.1:3000″,
“Sec-WebSocket-Origin”=>”http://127.0.0.1:3000″,
“Host”=>”localhost:10081″,
“Connection”=>”Upgrade”,
“upgrade”=>”websocket”
}
Safari的header是:
{
“sec-websocket-key1″=>”`4Q2;w/M3 = d Q_58995’6Z6″,
“Sec-WebSocket-Key1″=>”`4Q2;w/M3 = d Q_58995’6Z6″,
“sec-websocket-key2″=>”1]2&6477% “1]2&6477% “Upgrade”,
“origin”=>”http://127.0.0.1:3000″,
“Upgrade”=>”WebSocket”,
“Origin”=>”http://127.0.0.1:3000″,
“host”=>”localhost:10081″,
“Host”=>”localhost:10081″,
“Connection”=>”Upgrade”,
“upgrade”=>”WebSocket”
}
大大,一定要XAMPP吗?我是自己安装的php+apache,运行不了命令行,所以导致我只有Socket Status: 0 Socket Status: 3 (Closed)?
求运行。
这里面的例子不能运行的,大家都去google code 里面下载一个php websocket 的正确代码吧http://code.google.com/p/phpwebsocket/
[...] HTML5 WebSockets 基础使用教程 (来自:彬GO) [...]
我要评论 >>