swoole如何连接远程有auth认证的redis?
参考文档
先安装下swoole/ide-helper,他能给你起到很大的帮助,下载地址:https://github.com/swoole/ide-helper
初学者还是建议使用phpstrom编辑器,个人觉得提示功能很棒。
<?php
//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9502);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
var_dump($request->fd, $request->get, $request->server);
$ws->push($request->fd, "hello, welcome\n");
$redis = new Swoole\Coroutine\Redis();
$conn=$redis->connect('192.168.1.149', 6379);//redis绑定的主机、端口号
$redis->auth('admin');//redis 密码,没有设置的可以不用这一行
$redis->select('2');//选择操作的库,默认16个库,看你翻那个的牌子
$redis->get("key");//获取
$redis->set('testkey','testValue');//设置
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
// echo "Message: {
$frame->data}\n";
$redis = new Swoole\Coroutine\Redis();
$conn=$redis->connect('192.168.1.149', 6379);
$redis->auth('admin');
$redis->select('2');
$message=$redis->get("testkey");
$ws->push($frame->fd, $message);
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{
$fd} is closed\n";
});
$ws->start();
?>
运行方法 php Swoole_server.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/10/29
* Time: 1:38
*/
namespace App\Http\Commom;
use Swoole\Coroutine\Redis;
class Swoole_server
{
/**
* host websocket 主机
* port websocket 端口
* self::redis_host redis绑定的主机
* self::redis_port redis绑定的端口
* rpassword redis密码
* rDB redis数据库名称(0--15)
*/
const host='0.0.0.0';
const port=9502;
const redis_host='192.168.1.149';
const redis_port='6379';
const redis_password='admin';
const redis_DB='2';
public function __construct()
{
$ws=new \swoole_websocket_server(self::host,self::port);
/**
* 参考文档地址
* https://wiki.swoole.com/wiki/page/13.html
* $ws->set必须在Server->start前调用
* max_conn => 10000, 此参数用来设置Server最大允许维持多少个tcp连接。超过此数量后,新进入的连接将被拒绝。
* daemonize => 1,加入此参数后,执行php server.php将转入后台作为守护进程运行
* reactor_num => 2,通过此参数来调节Reactor线程的数量,以充分利用多核;reactor_num和默认设置为CPU核数
* worker_num => 4,设置启动的Worker进程数量。Swoole采用固定Worker进程的模式。
* backlog => 128,此参数将决定最多同时有多少个待accept的连接,swoole本身accept效率是很高的,基本上不会出现大量排队情况。
* open_cpu_affinity => 1 ,启用CPU亲和设置
* open_tcp_nodelay => 1 ,启用tcp_nodelay
* tcp_defer_accept => 5,此参数设定一个秒数,当客户端连接连接到服务器时,在约定秒数内并不会触发accept,直到有数据发送,或者超时时才会触发。
* log_file => '/data/log/swoole.log', 指定swoole错误日志文件。在swoole运行期发生的异常信息会记录到这个文件中。默认会打印到屏幕。
* dispatch_mode = 1 //1平均分配,2按FD取模固定分配,3抢占式分配,默认为取模(dispatch=2)
*/
$ws->set(array(
'reactor_num' => 2, //reactor thread num
'worker_num' => 4, //worker process num
'backlog' => 128, //listen backlog
'max_request' => 50,
'dispatch_mode' => 5,//发送模式:1平均分配,2按FD取模固定分配,3抢占式分配,默认为取模(dispatch=2),绑定时设置为5
'daemonize' => 1,//在后台运行
'log_file' => '/var/log/swoole.log',//开机运行时请指定日志,打开daemonize,便于排错
));
$ws->on('open',[$this,'Open']);
$ws->on('message',[$this,'Message']);
$ws->on('close',[$this,'Close']);
/**
*运行模式
* php Swoole_server.php
*
* 开机启动
* 如果想要在开机启动时,自动运行你的Server,可以在/etc/rc.local文件中加入
* /usr/bin/php /file_path/Swoole_server.php
*
* 不知道php位置可以使用which php命令查看
*
* 推荐使用systemd或supervisor实现服务管理。
*
*/
$ws->start();
}
/**
* @param $ws
* @param $request
* 监听websocket事件
*/
public function Open($ws, $request) {
/**
* $request->server['query_string'] URL中传递过来的参数
* $request->fd 获取fd
*
*/
$uid=($request->server['query_string']);//获取客户端传来的uid
$fd=$request->fd;//获取当前链接fd
var_dump("用户 $uid 已连接,当前fd为:$fd");
$fdinfo = $ws->getClientInfo($fd);
$redis = new Redis();
$conn=$redis->connect(self::redis_host, self::redis_port);//链接redis
if ($conn){
var_dump("链接redis成功!!");
}else{
var_dump("错误:链接redis失败,请检查端口服务或配置是否正常!");
}
$pwd=$redis->auth(self::redis_password);//验证密码
if ($pwd){
var_dump("redis密码验证成功!!");
}else{
var_dump("错误:redis密码错误或redis没有设置密码,请检查redis配置文件!");
}
$redis->select(self::redis_DB);//选择redis数据库
// var_dump("客户端链接绑定信息前");
// var_dump($fdinfo);
//判断当前fd是否被绑定过,
var_dump($fdinfo['uid']);
if (!$fdinfo['uid']){
$ws->bind($fd,$uid);
$redis->set($uid,$fd);
}else{
$db_fd=$redis->get($uid);
if ($db_fd!=$fd)
{
$redis->set($uid,$fd);
}
}
var_dump("客户端链接绑定信息后");
var_dump($ws->getClientInfo($fd));
// $start_fd=0;
// $conn_list = $ws->getClientList($start_fd, 10);
// var_dump("链接列表:$conn_list");
// if (!$fdinfo){
// }else{
// var_dump($fdinfo);
// }
}
/**
* 监听WebSocket消息事件
* @param $ws
* @param $frame
*/
public function Message($ws, $frame) {
// echo "Message: {
$frame->data}\n";
// var_dump(json_decode($frame->data));
/**
* $data 为客户端发过来的消息json
* $data->content 消息主体
* $data->sender 消息发送人name
* $data->target 消息接收人name
*/
$data = json_decode($frame->data);
$message = $data->content;
var_dump($message);
$redis = new Redis();
$conn=$redis->connect(self::redis_host, self::redis_port);
$redis->auth(self::redis_password);
$redis->select(self::redis_DB);
$target_fd=$redis->get($data->target);//获取目标fd
var_dump("发送到:$target_fd");
$ws->push($target_fd, $message);
$conn_list = $ws->getClientList(0, 10);
var_dump($conn_list);
}
/**
* 监听WebSocket连接关闭事件
* @param $ws
* @param $fd
*/
public function Close($ws, $fd) {
echo "client-{
$fd} is closed\n";
}
public function chat(){
$start_fd = 0;
while(true)
{
$conn_list = $ws->getClientList($start_fd, 10);
if ($conn_list===false or count($conn_list) === 0)
{
echo "finish\n";
break;
}
$start_fd = end($conn_list);
var_dump($conn_list);
foreach($conn_list as $fd)
{
$ws->send($fd, "broadcast");
}
}
}
}
$obj = new Swoole_server();