定义
Websocket是基于TCP的一种新的网络协议。
它实现了浏览器与服务器全双工通信——允许服务器主动发送信息给客户端。
为什么需要websocket?
1)HTTP的通信,只能由客户端发起;
2)websock有以下特点:
- 建立在TCP协议上
- 性能开销小,通信高效
- 客户端可以与任意服务器通信
- 协议标识符ws wss
- 持久化网络通信协议(长链接)
使用websocket
WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。
握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。
(1) 创建websocket对象
(2)完成连接事件(可选)
当WebSocket客户端与服务器建立连接并完成握手后,会回调此函数。
$ws->on('open', function ($ws, $request) {
...
});
(3)收到客户端数据事件(必选)
$ws->on('message', function ($ws, $frame) {
...
});
$frame 是swoole_websocket_frame对象,包含了客户端发来的数据帧信息。
详情请看下图:
(4)推送数据到客户端
// 第一种模式1.7.11+可用
$ws->push(int $fd, string $data, int $opcode = 1, bool $finish = true);
// 第二种模式4.2.0+可用
$ws->push(obj $data);
$opcode:
- 1 ,文本数据
- 2 ,二进制数据
swoole_websocket_frame对象
完整实例
<?php
//创建websocket服务器对象,监听0.0.0.0:8812端口
$ws = new swoole_websocket_server("0.0.0.0", 8812);
// 2.设置,如果访问静态资源,将不会走下面的逻辑
$ws->set([
'enable_static_handler' => true,
'document_root' => "/swoole/static"
]);
// 3.监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
// 服务器端打印如下信息
var_dump($request->fd, $request->get, $request->server);
// 客户端输出如下信息
$ws->push($request->fd, "客户端{$request->fd}连接服务器\n");
});
// 4.监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
// 服务器端打印如下信息
echo "收到来自客户端的信息:{$frame->data}\n";
// 客户端输出如下信息
$ws->push($frame->fd, "收到来自客户端的信息:{$frame->data}");
});
// 5.监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "客户端{$fd}断开连接\n";
});
// 5.启动服务器
$ws->start();
完整实例(oop)
<?php
class Ws
{
const HOST = "0.0.0.0";
const PORT = 8812;
public $ws = null;
public function __construct(){
// 1.创建websocket对象
$this->ws = new swoole_websocket_server(self::HOST, self::PORT);
// 2.设置,如果访问静态资源,将不会走下面的逻辑
$this->ws->set([
'enable_static_handler' => true,
'document_root' => "/swoole/static"
]);
// 3.各种事件
$this->ws->on("open",[$this,'onOpen']);
$this->ws->on("message",[$this,'onMessage']);
$this->ws->on("close",[$this,'onClose']);
// 5.开启服务器
$this->ws->start();
}
/**
* onOpen事件——监听WebSocket连接打开事件
* @param $ws websocket服务器对象
* @param $request Http请求对象
*/
public function onOpen($ws,$request){
// 服务器打印客户端socket id
echo "客户端id{$request->fd}连接服务器";
}
/**
* onMessage事件——监听WebSocket消息事件
* @param $ws websocket服务器对象
* @param $frame swoole_websocket_frame对象
*/
public function onMessage($ws,$frame){
// 服务器打印如下信息
echo "收到来自客户端{$frame->id}的数据:{$frame->data}\n";
// 向客户端输出如下信息
$ws->push($frame->fd, "ws服务器收到来自客户端{$frame->fd}的数据: {$frame->data}");
}
/**
* onClose事件——监听WebSocket连接关闭事件
* @param $ws websocket服务器对象
* @param $fd 客户端socket id
*/
public function onClose($ws,$fd){
// 服务器打印如下信息
echo "客户端{$fd}断开连接\n";
}
}
// 实例化
$obj = new Ws();