对于think-swoole网上资料五花八门,根据网上资料,我成功走上了岔路口,但是websocket连接时也可以走通,因为项目比较急,既然能走通那就直接用,也做成了满足需求的聊天软件,但是本着质量至上的态度,我又把代码改了一份正规的路线,下面分享我的 websocket自研路线 ,紧分享学习路程,不建议使用,正规路线在最下方。
安装think-swoole
具体操作
config/swoole.php
复制一份think\swoole\websocket\socketio\Handler.php到app\http\Ywliveanchor.php
app\http\Ywliveanchor.php
<?php
namespace app\http;
use Swoole\Server;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server as WebsocketServer;
use think\Config;
use think\Request;
use think\swoole\contract\websocket\HandlerInterface;
class Ywliveanchor implements HandlerInterface
{
/** @var WebsocketServer */
protected $server;
/** @var Config */
protected $config;
public function __construct(Server $server, Config $config)
{
$this->server = $server;
$this->config = $config;
}
/**
* "onOpen" listener.
*
* @param int $fd
* @param Request $request
*/
public function onOpen($fd, Request $request)
{
echo "队列{$fd}连接\n";
}
/**
* "onMessage" listener.
* only triggered when event handler not found
*
* @param Frame $frame
* @return bool
*/
public function onMessage(Frame $frame)
{
$packet = $frame->data;
if (Packet::getPayload($packet)) {
return false;
}
$this->checkHeartbeat($frame->fd, $packet);
return true;
}
/**
* "onClose" listener.
*
* @param int $fd
* @param int $reactorId
*/
public function onClose($fd, $reactorId)
{
return;
}
protected function checkHeartbeat($fd, $packet)
{
$packetLength = strlen($packet);
$payload = '';
if ($isPing = Packet::isSocketType($packet, 'ping')) {
$payload .= Packet::PONG;
}
if ($isPing && $packetLength > 1) {
$payload .= substr($packet, 1, $packetLength - 1);
}
if ($isPing) {
$this->server->push($fd, $payload);
}
}
}
标准的websocket连接方式使用原生swoole处理即可
逻辑完成后
php think swoole
开启多服务时报错:swoole http server process is already running.
think\swoole\command\Server.php
注释掉
// if ($pidManager->isRunning()) {
// $this->output->writeln('<error>swoole http server process is already running.</error>');
// return;
// }
示例逻辑
public function onMessage(Frame $frame)
{
\go(function ()use($frame) {
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$data=json_decode($frame->data);
// var_dump($data);
// if($data->con=='not_logged_in'){
// //未登录
// //存储房间信息
// $redis->sAdd('room'.$data->roominfo->id,$frame->fd);
// $redis->set('fd_roominfo'.$frame->fd,json_encode($data->roominfo));
// }else
if($data->con=='already_logged_in'){
// //已登录存储用户信息
//1.提供user列表
$redis->set('fd_userinfo'.$frame->fd,json_encode($data));//fd绑定info消息
$redis->zAdd('user'.$data->roominfo->id,$frame->fd,json_encode($data));// 有序集合记录房间info列表信息
$info=$redis->zRevRange('user'.$data->roominfo->id, 0, -1);//获取房间info列表信息
//2.提供user单个信息
// $redis->set('fd_userinfo'.$frame->fd,json_encode($data->userinfo));//fd绑定userinfo
// $userinfo=$redis->get('fd_userinfo'.$frame->fd);
//存储房间信息
$redis->set('fd_roominfo'.$frame->fd,json_encode($data->roominfo));//fd绑定房间
$redis->sAdd('room'.$data->roominfo->id,$frame->fd);//无序集合记录房间fd列表
$room=$redis->sMembers('room'.$data->roominfo->id);//获取房间fd列表
var_dump($room);
$res=array(
'open'=>'1',
//'data'=>['con'=>'open','msg'=>'发送成功','count'=>count($room),'info'=>json_decode($userinfo)]
'data'=>['con'=>'open','msg'=>'发送成功','count'=>count($room),'info'=>$info]
);
}elseif($data->con=='already_logged_out'){
$roominfo= json_decode($redis->get('fd_roominfo'.$frame->fd));//获取房间信息
$redis->srem('room'.$roominfo->id,$frame->fd);//删除房间信息
$room=$redis->sMembers('room'.$roominfo->id); //获取房间fd列表
var_dump($room);
//1.提供user列表
$data=$redis->get('fd_userinfo'.$frame->fd);//获取关闭用户的info信息
// var_dump($data);
$a=$redis->zRem('user'.$roominfo->id,$data);
// var_dump($a);
$info=$redis->zRevRange('user'.$roominfo->id, 0, -1);
$redis->del('fd_userinfo'.$frame->fd);//移除房间用户
// var_dump($info);
//2.提供user单个信息
// $userinfo=$redis->get('fd_userinfo'.$frame->fd);
// $redis->del('fd_userinfo'.$frame->fd);
$res=array(
'open'=>'1',
//'data'=>['con'=>'close',"count"=>count($room),'info'=>json_decode($userinfo)]
'data'=>['con'=>'close','msg'=>'发送成功','count'=>count($room),'info'=>$info]
);
echo "队列{$frame->fd}关闭1\n";
}
\go(function ()use($res,$room) {
$jsonStr = json_encode($res);
foreach($room as $fd){
$this->server->push($fd, $jsonStr);
}
});
}