什么是WebSocket
WebSocket协议是基于TCP的一种新的网络协议。他实现了浏览器与服务器全双工通信—允许服务器主动发送信息给客户端。
WebSocket特点
建立在TCP协议之上
性能开销小性能高效
客户端可以与任意服务器通信
协议标识符号 ws wss
持久化网络通信协议
WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。
建立连接后客户端与服务器端就可以双向通信了。
客户端向服务器端发送信息时,服务器端触发onMessage事件回调
服务器端可以调用$server->push()向某个客户端(使用$fd标识符)发送消息
服务器端可以设置onHandShake事件回调来手工处理WebSocket握手
swoole_http_server是swoole_server的子类,内置了Http的支持
swoole_websocket_server是swoole_http_server的子类, 内置了WebSocket的支持。
创建WebSocket.php
$server = new Swoole\WebSocket\Server("0.0.0.0", 8812);
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
echo "server: handshake success with fd{$request->fd}\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$server->push($frame->fd, "this is server");
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();
onRequest回调
WebSocket\Server 继承自 Http\Server
设置了onRequest回调,WebSocket\Server也可以同时作为http服务器
未设置onRequest回调,WebSocket\Server收到http请求后会返回http 400错误页面
如果想通过接收http触发所有websocket的推送,需要注意作用域的问题,面向过程请使用global对WebSocket\Server进行引用,面向对象可以把WebSocket\Server设置成一个成员属性
创建ws_client.html
var wsServer = 'ws://127.0.0.1:8812';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
websocket.send("hello websocket world");
console.log("Connected to WebSocket server.");
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
测试
1、通过httpserver来开启:分别执行swoole-http服务、websocket服务文件启动服务,浏览器访问http://127.0.0.1:8811/ws_client.html,注意这里请求的是8811端口,即httpserver中配置的端口,在控制台中查看效果。同时可在浏览器开启多个会话,查看多个连接效果。
2、通过websocket-server来开启加载:
在websocket-server中添加配置
$server->set(
[
'enable_static_handler' => true,
'document_root' => '/opt/work/htdocs/swoole_mooc/demo/data',
]
);
此时关闭http-server、websocket-server,并重启websocket-server,不再重启http-server,使用8812端口在浏览器访问http://127.0.0.1:8812/ws_client.html,同样成功。