2020-05-07 18:06:00
围观(6733)
用 PHP 写即时聊天一般是用 Workerman 或者 Swool, 博主之前有使用 Workerman 写过简单的多人聊天, 今天看到一个项目使用了 GatewayWorker , 就学习了一下.
GatewayWorker 官方手册: http://doc2.workerman.net/
GatewayWorker 是基于 Workerman 开发的, GatewayWorker 提供了一些 API 可以更方便的调用, 减少了重复写轮子的时间.
使用命令安装 Laravel:
composer create-project --prefer-dist laravel/laravel im 7.*

安装完成后 进入到 Laravel 目录, 开始安装 Workerman ( Workerman 手册: http://doc.workerman.net/install/install.html ):
composer require workerman/workerman

接着就要安装 GatewayWorker 和 GatewayClient
composer require workerman/gateway-worker
composer require workerman/gatewayclient
依赖的类库和包都装好了, 接着就是写逻辑代码, 可以进入 GatewayWorker 的手册 下载提供的 DEMO

在项目根目录创建一个 workerman 目录, 将 DEMO 提供的一些文件粘贴进去

打开 start_gateway.php / start_businessworker.php / start_register.php 将自动加载类文件的路径修改:
require_once __DIR__ . '/../../../vendor/autoload.php';
以及把 start_gateway.php 文件的协议修改成 Websocket:
$gateway = new Gateway("Websocket://0.0.0.0:8282");此时双击 workerman 目录下的 start_for_win.bat 可以正常运行:

当然, 在 Laravel 里面使用, 就不能使用 Events.php 写业务逻辑了, Events.php 只需要返回 $client_id 就行了.
例如将 Events.php 的 onMessage 及 onClose 里的代码都注释 onConnect 方法改成:
public static function onConnect($client_id)
{
// 向当前client_id发送数据
Gateway::sendToClient($client_id, $client_id);
}这样前端在连接后端的 Websocket 时, 就能拿到 client_id, 后续请求接口携带 client_id 就能与其他用户一起通信了.
在 API 写一条路由:
Route::get('send_msg', 'SendMsgController@send');使用命令创建控制器(其实按照规范 应该是在控制器目录下的 API 目录的 这里为了简单):
php artisan make:controller SendMsgController
创建完成后, 在 SendMsgController 控制器写入 send 方法:
public function send(Request $request)
{
$input = $request->all();
if (isset($input['client_id']) && $input['content']) {
Gateway::$registerAddress = '127.0.0.1:1238';
Gateway::sendToAll("{$input['client_id']} 说: {$input['content']}");
}
}send 方法的 127.0.0.1:1238 对应的是 start_gateway.php / start_businessworker.php / start_register.php 这三个文件的注册地址, 需要要改地址或者端口 需要全都改.
不要忘了需要引入类:
use GatewayClientGateway;
另外, 在本地测试, 还需要配置一下环境 (因为使用 PHPStudy 很简单配置 所以不细说):

有了后端, 就差前端, 写一个 test.html:
<!DOCTYPE html>
<html>
<head>
<title>不败君 - www.bubaijun.com</title>
<meta charset="utf-8">
</head>
<body>
<input type="text" name="" id="content">
<button id="send">send</button>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
var ws = new WebSocket("ws://127.0.0.1:8282");
ws.onopen = function() {
document.getElementById('send').addEventListener('click', function(){
var client_id = localStorage.getItem("client_id");
if (!client_id) {
return;
console.log('缺少参数');
}
var content = document.getElementById('content').value;
$.ajax({
url: 'http://im.test/api/send_msg?client_id=' + client_id + '&content=' + content,
type: 'GET',
});
}, false)
};
var open = true;
ws.onmessage = function (evt) {
if (open) {
var client_id = evt.data;
localStorage.setItem("client_id", client_id);
}
open = false;
console.log(evt.data);
};
</script>
</body>
</html>打开两个或者多个浏览器按 F12 或者手动打开控制台(开发者工具).
发送消息测试:

前端与后端通信成功后, 可以修改前端让界面更美观而不是用控制台, 后端也可以修改加上更多功能.
更详细的介绍可以看官方手册的这个: http://doc2.workerman.net/326107
本文地址 : bubaijun.com/page.php?id=178
版权声明 : 未经允许禁止转载!
上一篇文章: Python生成十万个无序且唯一的数字
下一篇文章: 使用PHP Laravel 框架开发淘客站点