WebSocket是HTML5的一项功能,用于在Web浏览器和服务器之间建立套接字连接,与服务器建立连接后,所有WebSocket数据(框架)都直接通过套接字发送,而不是通常的HTTP响应和请求,使我们能够在Web浏览器和服务器之间进行更快,持续的通信。让我们使用这项很酷的技术(HTML5 WebSocket和PHP)创建一个简单的聊天系统。
浏览器支持
旧的浏览器不支持WebSockets,您需要支持HTML5 WebSocket功能的最新浏览器。请访问caniuse.com来查找所有WebSocket支持的浏览器。
WebSocket入门
客户端的WebSocket实现非常简单,整个代码由很少的方法和事件组成。例如,看下面的代码。
//create a new WebSocket object.
websocket = new WebSocket("ws://localhost:9000/daemon.php");
websocket.onopen = function(evt) { /* do stuff */ }; //on open event
websocket.onclose = function(evt) { /* do stuff */ }; //on close event
websocket.onmessage = function(evt) { /* do stuff */ }; //on message event
websocket.onerror = function(evt) { /* do stuff */ }; //on error event
websocket.send(message); //send method
websocket.close(); //close method
要打开套接字连接,我们只需调用new WebSocket(ws:// SERVER URL)即可,因为WebSocket对连接使用了不同的协议,所以我们使用ws://代替http://,然后加上主机,端口号和服务器中的守护程序脚本:打开连接后,我们需要附加一些事件处理程序,以使我们知道连接状态,错误和传入消息,以供您参考:
- WebSocket(wsUri) —创建一个新的WebSocket对象。
- .onopen —建立连接时发生事件。
- .onclose —关闭连接时发生事件。
- .onmessage-客户端从服务器接收数据时发生的事件。
- .onerror —发生错误时发生事件。
- .send(message) -使用开放连接将数据传输到服务器。
- .close() —终止现有连接。
您可以像这样在网页中使用jQuery支持实现WebSocket。
$(document).ready(function(){
//Open a WebSocket connection.
var wsUri = "ws://localhost:9000/daemon.php";
websocket = new WebSocket(wsUri);
//Connected to server
websocket.onopen = function(ev) {
alert('Connected to server ');
}
//Connection close
websocket.onclose = function(ev) {
alert('Disconnected');
};
//Message Receved
websocket.onmessage = function(ev) {
alert('Message '+ev.data);
};
//Error
websocket.onerror = function(ev) {
alert('Error '+ev.data);
};
//Send a Message
$('#send').click(function(){
var mymessage = 'This is a test message';
websocket.send(mymessage);
});
});
聊天页面
如上面示例中所述,我们首先创建一个WebSocket对象,附加事件处理程序,然后使用websocket.send()方法发送数据。由于我们正在发送聊天值的集合,例如用户名,消息,颜色等,因此我们将在将数据发送到服务器之前将其转换为JSON格式。
$(document).ready(function(){
//create a new WebSocket object.
var wsUri = "ws://localhost:9000/daemon.php";
websocket = new WebSocket(wsUri);
websocket.onopen = function(ev) { // connection is open
$('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
}
$('#send-btn').click(function(){ //use clicks message send button
var mymessage = $('#message').val(); //get message text
var myname = $('#name').val(); //get user name
if(myname == ""){ //empty name?
alert("Enter your Name please!");
return;
}
if(mymessage == ""){ //emtpy message?
alert("Enter Some message Please!");
return;
}
//prepare json data
var msg = {
message: mymessage,
name: myname,
color : '<?php echo $colours[$user_colour]; ?>'
};
//convert and send data to server
websocket.send(JSON.stringify(msg));
});
//#### Message received from server?
websocket.onmessage = function(ev) {
var msg = JSON.parse(ev.data); //PHP sends Json data
var type = msg.type; //message type
var umsg = msg.message; //message text
var uname = msg.name; //user name
var ucolor = msg.color; //color
if(type == 'usermsg')
{
$('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\">"+uname+"</span> : <span class=\"user_message\">"+umsg+"</span></div>");
}
if(type == 'system')
{
$('#message_box').append("<div class=\"system_msg\">"+umsg+"</div>");
}
$('#message').val(''); //reset text
};
websocket.onerror = function(ev){$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");};
websocket.onclose = function(ev){$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");};
});
以下是我们用于聊天系统的HTML,它带有一些基本样式,我这里没有包括CSS部分,但是您应该在示例文件中找到它。
<div class="chat_wrapper">
<div class="message_box" id="message_box"></div>
<div class="panel">
<input type="text" name="name" id="name" placeholder="Your Name" maxlength="10" style="width:20%" />
<input type="text" name="message" id="message" placeholder="Message" maxlength="80" style="width:60%" />
<button id="send-btn">Send</button>
</div>
</div>
使用PHP套接字的聊天服务器
好!现在,我们可以将聊天页面准备好连接到服务器,但是我们还需要创建一个永久运行(无超时),执行WebSocket握手,从聊天页面发送/接收数据并处理多个客户端的WebSocket服务器。将在PHP中创建一个守护程序脚本。每个人都知道PHP主要用于创建动态网页,但是我们大多数人都不知道我们也可以仅使用PHP来创建后台程序(在后台运行)。 安装WebSocket服务器 安装本地Web服务器,例如WAMP或XAMPP。我在Win-XP上使用XAMPP服务器,它使我可以使用shell选项启动守护程序脚本。我不确定WAMP是否具有相同的功能,但是您可以在此处遵循Dani的解决方案运行此服务器脚本。如果要在网站上实现它,请首先检查主机是否允许您运行守护程序脚本和shell命令。
PHP套接字步骤 我们将使用PHP套接字创建WebSocket聊天服务器,基本上,我们的PHP聊天服务器应执行以下操作。
- 打开Socket。
- 绑定到一个地址。
- 监听传入的连接。
- 接受连接。
- WebSocket握手。
- 取消屏蔽/编码数据帧。
打开一个套接字: 首先,我们使用PHP socket_create(Domain,Type,Protocol)创建一个套接字,如下所示:
//Create TCP/IP sream socket and return the socket resource
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
绑定到地址: 将名称绑定到套接字,这必须在使用socket_connect()或socket_listen()建立连接之前完成。
// Bind the source address
socket_bind($socket, 'localhost');
侦听传入连接: 创建套接字后,我们希望服务器侦听该套接字上的传入连接。
// Listen to incoming connection
socket_listen($socket);
接受连接: 此功能将接受传入的连接。
// Accept new connections
socket_accept($socket);
握手: 客户端必须通过发送WebSocket握手请求以建立与服务器的成功连接来自我介绍,握手请求中包含一个Sec-WebSocket-Key,该密钥是base64编码的随机生成的16字节值。然后服务器读取密钥,附加魔术字符串“ 258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,将哈希密钥与SHA1一起,以Sec-WebSocket-Accept的形式返回以base64编码的密钥。
PHP的握手响应:
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/deamon.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
取消屏蔽/编码数据帧。 握手之后,客户现在可以发送和接收短信,但发送的消息都是加密的,所以如果我们想显示他们所描述的每个数据帧需要取消屏蔽参考这里
启动聊天服务器
现在是时候通过单击下面的下载按钮下载示例文件了,您应该找到2个PHP文件,index.php和server.php。使用XAMPP中的Shell命令行界面,通过键入以下命令来启动WebSocket聊天服务器:
php -q server.php
服务器启动后,您可以使用浏览器导航到index.php页面并开始测试聊天。