以前咱们已经简单的了解过了websocket的使用了 php
简单使用:https://www.wj0511.com/site/detail.html?id=248html
若是须要使用websocket的话,php须要安装swoole拓展,安装swoole拓展能够参考react
windows下安装swoole拓展:https://www.wj0511.com/site/detail.html?id=246linux
linux下安装swoole拓展:https://www.wj0511.com/site/detail.html?id=247web
这里我来详细的说明下websocket在服务端所须要使用到的方法及属性算法
一:建立websocket服务器对象windows
在使用websocket以前首先须要建立一个websocket服务器对象数组
$server = new \swoole_websocket_server($host, $port);
参数说明:浏览器
$host:websocket须要监听的IP,0.0.0.0 表示监听全部IP地址服务器
$port:websocket须要监听的端口号
根据如上如:
$server = new \swoole_websocket_server('0.0.0.0', '8888');
如上代码表示建立一个websocket服务器对象并监听0.0.0.0:8888
二:设置运行参数
建立websocket服务器对象后,咱们能够设置websocket运行时的各项参数,这时候使用到set方法
$server->set(array $setting);
参数说明:
$server:建立websocket服务器对象返回的对象
$setting:websocket运行各项参数,$setting是一个数组参数
常见的运行参数有:
1:事件处理线程的数量(reactor_num)
'reactor_num' => 2, //经过此参数来调节主进程内事件处理线程的数量,以充分利用多核。默认会启用CPU核数相同的数量。通常设置为CPU核数的1-4倍
2:设置启动的Worker进程数(worker_num)
'worker_num' => 4, //若是业务代码是全异步非阻塞时,这里设置为CPU的1-4倍最合理,若是业务代码为同步阻塞,须要根据请求响应时间和系统负载来调整
3:设置worker进程的最大任务数(max_request)
'max_request' => 50, //此参数表示worker进程在处理完n次请求后结束运行。并从新建立一个worker进程。此选项用来防止worker进程内存溢出
4:设置最大最大容许的链接数(max_connection)
'max_connection' => 1000, //此参数用来设置Server最大容许维持多少个TCP链接。超过此数量后,新进入的链接将被拒绝
5:数据包分配模式(dispatch_mode)
'dispatch_mode' => 1, //1平均分配,2按FD取模固定分配,3抢占式分配,默认为取模(dispatch=2)
6:当dispatch_mode参数设置为1和3时,这时候系统会默认关闭onConnect/onClose事件,这时候若是你须要onConnect/onClose事件,这时候你须要设置enable_unsafe_event为true
'enable\_unsafe\_event' => true,
7:日志文件路径(log_file)
'log_file' => '/data/log/swoole.log', // 指定swoole错误日志文件地址,默认错误日志会打印到页面上
8:设置websocket错误日志打印等级(log_level),范围是0-5
'log_level' => 1, //低于log_level设置的日志信息不会抛出
9:进程的PID存储文件地址(pid_file)
'pid_file' => '/data/log/server.pid',
10:启动TCP-Keepalive死链接检测(open_tcp_keepalive)
'open\_tcp\_keepalive' => 1
11:指定秒中若是没有数据请,对此链接进行检测(tcp_keepidle)
'tcp_keepidle' => 5,
12:超过指定探测次数,关闭此链接(tcp_keepcount)
'tcp_keepcount' => 5,
13:设置探测的间隔事件,单位为秒(tcp_keepinterval)
'tcp_keepinterval' => 3
14:心跳检测机制
(1)heartbeat_check_interval
'heartbeat_check_interval' => 5, //心跳检测,此选项表示每隔多久轮循一次,单位为秒
(2)heartbeat_idle_time
'heartbeat_idle_time' => 15, //心跳检测,链接最大容许空闲的时间
15:守护进程化(daemonize)
'daemonize' => 1, //正常状况下执行websocket脚本时,会在命令行显示运行过程,当此参数设置为1时,这时候websocket脚本将转入后台做为守护进程运行
如上就是websocket一些经常使用的运行参数,使用set方法设置运行参数简单实例以下
$server->set([ 'max_request' => 50, ]);
若是你不想要本身进行设置运行参数的话,能够不适用set方法,这时候系统会使用默认的运行参数
三:注册websocket事件的回调函数
在websocket中咱们可使用on方法来注册指定事件的回调函数
$server->on(string $event, mixed $callback);
参数说明:
$server:建立websocket服务器对象返回的对象
$event:须要注册的事件名称,此参数须要将事件名称前面的on字符去除
$callback:回调的PHP函数,能够是函数名的字符串,类静态方法,对象方法数组,匿名函数
常见的事件有:
1:onStart:websocket启动后事件,onStart回调中,仅容许echo、打印Log、修改进程名称。不得执行其余操做
如:
$server->on('start', function($server) { echo 'server 启动'; echo "\n"; echo 'websocket进程ID为' . $server->master_pid; });
2:onHandShake:WebSocket创建链接后进行握手事件,WebSocket服务器已经内置了握手事件,若是用户但愿本身进行握手处理,能够设置onHandShake事件回调函数
这里注意,若是你设置了握手事件的话,这时候你就不会再触发onOpen事件,这时候你就须要手动去触发onOpen事件
如:
$server->on('handshake', function($request, $response) use ($server) { echo '握手成功'; defaultHandshake($request, $response); //手动调用onOpen事件 $server->defer(function() use ($server, $request) { onOpen($server, $request); }); }); //默认的握手处理 function defaultHandshake($request, $response) { // websocket握手链接算法验证 $secWebSocketKey = $request->header['sec-websocket-key']; $patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#'; if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) { $response->end(); return false; } $key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); $headers = [ 'Upgrade' => 'websocket', 'Connection' => 'Upgrade', 'Sec-WebSocket-Accept' => $key, 'Sec-WebSocket-Version' => '13', ]; if (isset($request->header['sec-websocket-protocol'])) { $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol']; } foreach ($headers as $key => $val) { $response->header($key, $val); } $response->status(101); $response->end(); }
3:onOpen:当WebSocket客户端与服务器创建链接并完成握手后会回调此函数
如:
$server->on('open', function ($server, $request) { echo 'server 链接成功'; });
若是你设置了握手的话,能够这样写:
$server->on('open', function ($server, $request) { onOpen($server, $request); }); function onOpen($server, $request) { echo 'server 链接成功'; }
4:onMessage:当服务器收到来自客户端的数据帧时会回调此函数
$server->on('message', function ($server, $frame) { echo "客户端信息为" . $frame->data; });
5:onRequest:若是设置了onRequest回调,WebSocket也能够同时做为http服务器,及当直接在浏览器访问时,onRqeust事件会触发,若是不设置的话,收到http请求后会返回http 400错误页面
$server->on('request', function ($request, $response) { echo 'server 路由响应' });
6:onClose:webscoket客户端关闭链接后触发
//监听WebSocket链接关闭事件 $server->on('close', function ($server, $fd) { echo "客户端进程" . $fd . '关闭'; });
7:onShutdown:在websocket服务正常关闭时触发
$server->on('shutdown', function ($server) { echo 'websocket服务端关闭'; });
如上就是在websocket中常见的事件
四:启动websocket服务器
$server->start();
当咱们设置好websocket的运行参数和事件回调以后执行如上方法,这时候咱们的websocket服务器就启动了
五:向客户端发送消息
在websocket中使用push方法项客户端发送消息
$server->push($fd, $data);
参数说明:
$fd:客户端链接的ID
$data:要发送的数据内容
六:在websocket中常见的属性和方法
1:server对象能够获取的属性值和方法
(1):获websocket全部的运行参数
$server->setting
(2):获取websocket的主服务进程ID
$server->master_pid
(3):获取全部的客户端链接ID
[1]
$server->getClientList(0, 10) //参数1表示骑士的客户端链接ID,参数2表示每页显示的条数
[2]
foreach($server->connections as $fd) { echo $fd; }
这里推荐使用$server->connections获取客户端链接
(4):判断指定客户端链接ID是否存在
$server->exist($fd)
(5)判断指定客户端链接ID是否为已完成握手的WebSocket客户端链接
$server->isEstablished($fd)
(7):咱们能够主动将指定客户端链接关闭
$server->close($fd);//关闭指定客户端链接
2:request对象能够获取的属性值和方法
(1):获取当前链接的客户端链接ID
$request->fd
(2):获取客户端请求传递的参数
$request->get
如客户端地址为ws://127.0.0.1:8888?id=2时上面获取的方法返回为:
[ 'id' => 2 ]
(3)获取相关的服务器信息
咱们能够获取到客户端请求的路由
$request->server['request_uri']
如客户端地址为ws://127.0.0.1:8888/test时上面获取的方法返回为 /test
(4):获取客户端的请求头信息
$request->header
当咱们在客户端实例化websocket增长第二个参数时如
var wsServer = 'ws://127.0.0.1:8888'; var websocket = new WebSocket(wsServer, 'public');
这时候在服务端咱们就可使用以下方法获取到public值
$request->header['sec-websocket-protocol']
如上就是websocket在服务端的简单介绍了