TP使用workerman小程序通信
第一步:
Linux环境检查脚本
Linux用户可以运行以下脚本检查本地环境是否满足WorkerMan要求
curl -Ss https://www.workerman.net/check | php
如果脚本中全部提示ok,则代表满足WorkerMan运行环境
(注意:检测脚本中没有检测event扩展,如果并发连接数大于1024建议安装event扩展)
第二步:
Composer安装:
composer require workerman/workerman
第三步
服务端代码(里面有一些是我自己业务的逻辑代码,不要全部复制粘贴使用)<?php
namespace app\api\controller\v1;
use Workerman\Worker;
use app\common\controller\Api;
use app\common\library\Auth;
/**
* 接口
*/
class Weekly extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['openai'];
protected $auth = null;
protected $worker = null;
protected $userId = 0;
public function index(){
$this->auth = Auth::instance();
// 创建一个Worker监听9090端口,使用http协议通讯
$worker = new Worker("websocket://0.0.0.0:9090");
$this->worker = $worker;
// 启动4个进程对外提供服务
$worker->count = 4;
$worker->uidConnections = array();
$worker->onConnect = function ($connection){
print_r('第一次!');
};
// 接收到浏览器发送的数据时回复hello world给浏览器
//$http_worker->onMessage = function(TcpConnection $connection, Request $request)
$worker->onMessage = function ($connection, $request) use ($worker) {
// print_r($connection);
// foreach ($http_worker->connections as $connection) {
// $connection->send($request);
// }
$data = json_decode($request,true);
if(empty($data['token'])){
return;
}
$token = $data['token'];
//初始化
$this->auth->init($token);
$userinfoId = 0;
//检测是否登录
if (!$this->auth->isLogin()) {
print_r('没登录');
return;
}
// 判断当前客户端是否已经验证,既是否设置了uid
if (!isset($connection->uid)) {
print_r('登录');
$userinfo = $this->auth->getUserinfo();
$userinfoId = $userinfo['id'];
$this->userId = $userinfoId;
// 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证)
$connection->uid = $userinfoId;
/* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
* 实现针对特定uid推送数据
*/
print_r('用户uid:'.$connection->uid . '\n');
$worker->uidConnections[$connection->uid] = $connection;
// return;
}
$this->worker = $worker;
if(!empty($data['type'])&&$data['type']='openai'){
// print_r($data['type']);
$this->openai($data['data']['keyword'],$data['data']['wordNum'],$data['data']['type'],$data['data']['occupation']);
}
// $this->sendMessageByUid($worker, 2, 'hello world' . time());
// 向浏览器发送hello world
//$connection->send('hello world'.time());
};
// 当有客户端连接断开时
$worker->onClose = function ($connection) {
if (isset($connection->uid)) {
// 连接断开时删除映射
print_r('有用户断开:'.$connection->uid);
unset($this->worker->uidConnections[$connection->uid]);
}
};
Worker::runAll();
}
// 针对uid推送数据
private function sendMessageByUid($worker, $uid, $message,$expand=[])
{
if (isset($worker->uidConnections[$uid])) {
//print_r($worker->uidConnections[$uid] . ',发送个指定用户\n');
$connection = $worker->uidConnections[$uid];
$content = ['content'=>$message];
$data = [
'code'=>1,
'data'=>array_merge($expand,$content)
];
$connection->send(json_encode($data,true));
return true;
}else{
print_r('没触发');
return false;
}
}
/**
* $num 生成字数
* $type 生成类型
* $occupation 职业
* $keyword 关键词
*/
private function openai($keyword='',$num= '',$type='周报',$occupation=''){
if($num){
$num = '编写'.$num.'字';
}else{
$num = '把以下';
}
if($occupation){
$occupation = '软件开发专业';
}
$data = json_encode(['prompt'=>'请帮我'.$num.'的工作内容填充为一篇完整'.$occupation.'的'.$type.',用 markdown 格式以分点叙述的形式输出:'.$keyword]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, "https://xxxx.com" );
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_NOPROGRESS, FALSE);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this, 'apicallback'));
$result = curl_exec($ch); //***Note A***
curl_close($ch);
// print_r($result);
$this->sendMessageByUid($this->worker, $this->userId, '',['status'=>1]);
}
private function apicallback($clientp, $dltotal, $dlNow, $ultotal, $ulNow) {
// $contents = fread($clientp,"1");
$this->sendMessageByUid($this->worker, $this->userId, curl_multi_getcontent ($clientp),['status'=>0]);
// echo (curl_multi_getcontent ($clientp)).'/';
}
}
第四步
在项目根目录创建一个server.php文件用于启动workerman代码如下:
<?php
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','api/v1/Weekly');//这个路径根据自己项目目录修改
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';
第五步
在服务器终端启动workermanphp server.php index start
小程序端
连接,小程序必须使用wss(sll)连接,使用服务器域名转发
uni.connectSocket({
url: 'wss://v.zmmz.com/wss'
});
连接成功uni.onSocketOpen(function (res) { console.log('WebSocket连接已打开!');
uni.sendSocketMessage({
data: JSON.stringify({token:userInfo.token})
});
});
接收消息
uni.onSocketMessage(function (res) {
console.log(res.data)
});
发送消息uni.sendSocketMessage({
data: JSON.stringify({token:t.userInfo.token,type:'openai',data:{keyword:t.keyword,wordNum:t.array[t.index],type:t.type,occupation:t.occupation}})
});
nginx转发
#此处是重点代理wss协议输出
location /wss
{
proxy_pass http://127.0.0.1:端口;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
原创文章,转载请注明:TP使用workerman小程序通信 | 知识改变命运
转载请注明出处: 知识改变命运 » TP使用workerman小程序通信