基于 Swoole 实现简单的 WebSocket 服务器及客户端
与 HTTP 类似,WebSocket 协议对应的 scheme 是 ws,如果是加密的 WebSocket 对应的 scheme 是 wss。
WebSocket 服务器 PHP 异步网络通信引擎 Swoole 内置了对 WebSocket 的支持,通过几行 PHP 代码就可以写出一个异步非阻塞多进程的 WebSocket 服务器:
<?php
// 初始化 WebSocket 服务器,在本地监听 8000 端口
$server = new Swoole\WebSocket\Server("localhost", 8000);
// 建立连接时触发
$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");
});
// 关闭 WebSocket 连接时触发
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
// 启动 WebSocket 服务器
$server->start();
编写完成后,将这段 PHP 代码保存到本地 websocket_server.php 文件。
WebSocket 客户端
在客户端,可以通过 JavaScript 调用浏览器内置的 WebSocket API 实现 WebSocket 客户端,实现代码和服务端差不多,无论服务端还是客户端 WebSocket 都是通过事件驱动的,我们在一个 HTML 文档中引入相应的 JavaScript 代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Chat Client</title>
</head>
<body>
<script>
window.onload = function () {
var nick = prompt("Enter your nickname");
var input = document.getElementById("input");
input.focus();
// 初始化客户端套接字并建立连接
var socket = new WebSocket("ws://localhost:8000");
// 连接建立时触发
socket.onopen = function (event) {
console.log("Connection open ...");
}
// 接收到服务端推送时执行
socket.onmessage = function (event) {
var msg = event.data;
var node = document.createTextNode(msg);
var div = document.createElement("div");
div.appendChild(node);
document.body.insertBefore(div, input);
input.scrollIntoView();
};
// 连接关闭时触发
socket.onclose = function (event) {
console.log("Connection closed ...");
}
input.onchange = function () {
var msg = nick + ": " + input.value;
// 将输入框变更信息通过 send 方法发送到服务器
socket.send(msg);
input.value = "";
};
}
</script>
<input id="input" style="width: 100%;">
</body>
</html>
将这个 HTML 文档命名为 websocket_client.html。
WebSocket 通信演示
接下来,我们在命令行启动 WebSocket 服务器:
php websocket.php
然后在浏览器中访问 websocket_client.html,首先会提示我们输入昵称:
输入之后点击确定,JavaScript 代码会继续往下执行,让输入框获取焦点,然后初始化 WebSocket 客户端并连接到服务器,这个时候通过开发者工具可以看到 Console 标签页已经输出了连接已建立日志:在 Network 里面也可以看到 WebSocket 握手请求和响应:
这个时候我们在输入框中输入「你好,WebSocket!」并回车,即可触发客户端发送该数据到服务器,服务器接收到消息后会将其显示出来:
同时将「This is server」消息推送给客户端,客户端通过 onmessage 回调函数将获取到的数据显示出来。在开发者工具的 Network->WS 标签页可以查看 WebSocket 通信细节:
看起来,这个过程还是客户端触发服务器执行推送操作,但实际上,在建立连接并获取到这个客户端的唯一标识后,后续服务端资源有更新的情况下,仍然可以通过这个标识主动将更新推送给客户端,而不需要客户端发起拉取请求。WebSocket 服务器和客户端在实际项目中的实现可能会更加复杂,但是基本原理是一致的。
猜你喜欢
微擎常用记录
阅读 664微擎常用记录
Laravel邮箱推送
阅读 1789Laravel发送邮件
Layui富文本视频等多功能
阅读 620Layui富文本多功能添加
PHP定时任务
阅读 1597PHP框架Laravel定时任务的实现
在 Laravel 中集成 Swoole 实现 WebSocket 服务器
阅读 2286基于 LaravelS 扩展包把 Swoole 集成到 Laravel 项目来实现 WebSocket 服务器,以便与客户端进行 WebSocket 通信从而实现广播功能。
Git使用
阅读 592Git基本配置/服务器搭建仓库
黑客、后门
阅读 1426留下的网站后门,可以作什么?
Swoole 扩展安装与使用入门
阅读 1774Swoole从入门到实战