1、新建客户端client.html
<html>
<meta>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
</head>
<body>
<h3>WebSocket协议的客户端程序</h3>
<button id="btConnect">连接到WS服务器</button>
<button id="btSendAndReceive">向WS服务器发消息并接收消息</button>
<button id="btClose">断开与WS服务器的连接</button>
<div id="val"></div>
</body>
<script>
var wsClient = null; // WS客户端对象
btConnect.onclick = function(){
//连接到WS服务器,注意:协议名不是http!
wsClient = new WebSocket('ws://127.0.0.1:8000');
wsClient.onopen = function(){
console.log('WS客户端已经成功连接到服务器上')
}
}
btSendAndReceive.onclick = function(){
//向WS服务器发送一个消息
wsClient.send('Hello Server');
//接收WS服务器返回的消息
wsClient.onmessage = function(e){
console.log('WS客户端接收到一个服务器的消息:'+ e.data);
val.innerHTML=e.data;
}
}
btClose.onclick = function(){
//断开到WS服务器的连接
wsClient.close(); //向服务器发消息,主动断开连接
wsClient.onclose = function(){
//经过客户端和服务器的四次挥手后,二者的连接断开了
console.log('到服务器的连接已经断开')
}
}
</script>
</html>
2、新建服务端
<?php
class websocket{
public function __construct($address,$port)
{
//建立套接字
$this->soc=$this->createSocket($address,$port);
$this->socs=array($this->soc);
$this->run();
}
// 建立套接字
public function createSocket($address,$port)
{
//创建一个套接字
$socket= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//设置套接字选项
socket_set_block($socket);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//绑定IP地址和端口
socket_bind($socket,$address,$port);
//监听套接字
socket_listen($socket, 4);
return $socket;
}
public function run(){
// 挂起进程
$sock = $this->soc;
while(true){
echo "Waiting for Connection...\n";
$msgsock = socket_accept($sock); // 返回有效的套接字
echo "Waiting for Request...\n";
$buf = socket_read($msgsock, 8192); // 读取请求
echo "Request Received: $buf\n";
$response = $this->hand_shake($buf);
socket_write($msgsock,$response,strlen($response)); // 发送响应,让客户端知道连接成功;
//正式开始通信...
$buf = socket_read($msgsock, 8192);
for($i=0; $i<3; $i++){
$msg = "WELCOME $i\n";
$msg = $this->code($msg);
sleep(1);
socket_write($msgsock, $msg, strlen($msg)); // 发送消息到客户端
}
socket_close($msgsock);
}
socket_close($sock);
}
/**
* 套接字握手,可以不用管
* @param $buf
* @return string
*/
public function hand_shake($buf){
$buf = substr($buf,strpos($buf,'Sec-WebSocket-Key:')+18);
$key = trim(substr($buf,0,strpos($buf,"\r\n")));
$new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
$new_message = "HTTP/1.1 101 Switching Protocols\r\n";
$new_message .= "Upgrade: websocket\r\n";
$new_message .= "Sec-WebSocket-Version: 13\r\n";
$new_message .= "Connection: Upgrade\r\n";
$new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
return $new_message;
}
public function code($msg){
$msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg);
$frame = array();
$frame[0] = '81';
$len = strlen($msg);
$frame[1] = $len<16?'0'.dechex($len):dechex($len);
$frame[2] = $this->ord_hex($msg);
$data = implode('',$frame);
return pack("H*", $data);
}
public function ord_hex($data) {
$msg = '';
$l = strlen($data);
for ($i= 0; $i<$l; $i++) {
$msg .= dechex(ord($data{$i}));
}
return $msg;
}
}
// 调用
$address = '127.0.0.1';
$port = 8000;
$server = new websocket( $address, $port );
3、Windows的话,自己配置好php环境;下面执行命令php server.php运行服务端脚本。

4、浏览器,打开客户端,即可完成

本文介绍如何使用PHP搭建WebSocket服务端,并通过HTML客户端实现与服务器的实时双向通信。涵盖服务端握手、消息收发及客户端UI交互。
180

被折叠的 条评论
为什么被折叠?



