SWOFT之websocket
快速创建模块类
可以使用 swoftcli 工具来快速创建一个 websocket 模块类:
默认生成的是支持内置路由调度的模块类。
php swoftcli.phar gen:wsmod chat --prefix /chat
生成用户自定义调度的模块类。
php swoftcli.phar gen:wsmod chat --prefix /chat --tpl-file ws-module-user
示例: 简易的客户端 js 代码连接示例。
// wsUrl = websocket host + module path
const wsUrl = 'ws://127.0.0.1:18308/echo'
let ws = new WebSocket(wsUrl)
ws.onerror = function (event){
console.log("error: " + event.data)
}
ws.onopen = function (event){
console.log("open: connection opened");
}
ws.onmessage = function (event){
console.log("message: " + event.data);
}
ws.onclose = function (event){
console.log("close: connection closed")
ws.close()
}
这里我们使用 http://www.websocket.org/echo.html 简单测试使用下。

/**
* @OnOpen()
* @param Request $request
* @param int $fd
*/
public function onOpen(Request $request, int $fd): void
{
/* 数据库操作use Swoft\Db\DB;
$user = DB::table('user')->where('name', 'shuheng')->first();
if ($user) {
var_dump($user);
array(8) {
["id"]=>
int(1)
["times"]=>
int(1)
["status"]=>
int(1)
["report_id"]=>
int(1)
["is_run"]=>
int(2)
["execution_time"]=>
string(19) "2020-11-19 14:48:16"
["begin_time"]=>
string(19) "2020-11-26 14:27:34"
["end_time"]=>
string(19) "2020-11-26 14:27:34"
}
}*/
/* redis操作 use Swoft\Redis\Redis;
$scores = [
'key1' => 11,
'key3' => 11,
'key4' => 11,
'key2' => 21,
];
$result1 = Redis::zAdd('keys', $scores);
*/
// var_dump($request);
Session::current()->push("Opened, welcome #{$fd}!");
}
/**
* @OnMessage()
* @param Server $server
* @param Frame $frame
*/
public function onMessage(Server $server, Frame $frame): void
{
//拿到客户端发送的json消息并转成数组
$data = json_decode($frame->data,true);
//如果数组中不存在报告id,则提前关闭客户端连接
if(empty($data['report_id'])){
$server->close($frame->fd);
}
//创建get请求,请求外部接口
$report = $data['report_id'];
$url = 'dev-backend.pdvm.shuhengio.com';
$cli = new Client($url);
//$cli->setHeaders(['typ'=>'application/...']); //请求头参数
//$cli->post('/Progress/showoff',['report_id'=>1]); //post请求
$cli->get('/Progress/showoff?report_id='.$report);
$res = $cli->body;
$cli->close();
$res = json_decode($res,true);
if(empty($res['percentage'])){
$server->close($frame->fd);
}
$result = $res['percentage']*100;
$server->push($frame->fd,json_encode($res) );
//一定条件下循环发送数据给客户端
while ( (int)$result < 100){
$server->push($frame->fd,json_encode($res));
$cli = new Client($url);
$cli->get('/Progress/showoff?report_id='.$report);
$res = $cli->body;
$cli->close();
$res = json_decode($res,true);
if(empty($res['percentage'])){
$server->close($frame->fd);
}
$result = $res['percentage']*100;
//特定条件停止循环发送消息
if( (int)$result == 100 && $res['max_cycle_id'] == $res['cycle_id']){
$server->push($frame->fd,json_encode($res));
break;
}
sleep(1);
}
}