当前位置: 首页 > 工具软件 > Workerman > 使用案例 >

workerman客户端例子php,Workerman示例代码

壤驷兴朝
2023-12-01

`<?php `

`use` `Workerman\Worker;`

`use` `Workerman\WebServer;`

`use` `Workerman\Lib\Timer;`

`use` `PHPSocketIO\SocketIO;`

`include` `__DIR__ .` `'/vendor/autoload.php'``;`

`// 全局数组保存uid在线数据,一维数组,键为房间加上-uid,例如,web1-2924,为web_video的id为1的房间的2924用户`

`$uidConnectionMap` `= [];`

`// 全局数组保存房间在线数据,二维数组`

`$roomMap` `= [];`

`// 记录最后一次广播的在线用户数`

`$last_online_count` `= [];`

`// 记录最后一次广播的在线页面数`

`$last_online_page_count` `= [];`

`// PHPSocketIO服务`

`$socketIoPort` `= 2130;`

`$sender_io` `=` `new` `SocketIO(``$socketIoPort``);`

`// 客户端发起连接事件时,设置连接socket的各种事件回调`

`$sender_io``->on(``'connection'``,` `function` `(``$socket``) {`

`// 当客户端发来登录事件时触发`

`$socket``->on(``'login'``,` `function` `(``$uid``,` `$group``,` `$video_type``,` `$video_id``)` `use` `(``$socket``) {`

`global` `$uidConnectionMap``,` `$roomMap``,` `$last_online_count``,` `$last_online_page_count``,` `$socketIoPort``;`

`// 已经登录过了`

`if` `(isset(``$socket``->uid)) {`

`return``;`

`}`

`// 更新对应uid的在线数据`

`$uid` `= (string)``$uid``;`

`// 哪个房间`

`$room` `=` `$video_type` `.` `$video_id``;`

`// 哪个房间的哪个用户`

`$socket``->uid =` `$room` `.` `'-'` `.` `$uid``;`

`if` `(!isset(``$uidConnectionMap``[``$socket``->uid])) {`

`$uidConnectionMap``[``$socket``->uid] = 0;`

`}`

`if` `(!isset(``$roomMap``[``$room``][``$uid``])) {`

`$roomMap``[``$room``][``$uid``] = 0;`

`}`

`// 这个uid有++$uidConnectionMap[$uid]个socket连接`

`++``$uidConnectionMap``[``$socket``->uid];`

`++``$roomMap``[``$room``][``$uid``];`

`// 保存到文件,方便查看`

`$file` `=` `'/tmp/logs/socket/'` `.` `$socketIoPort` `.` `'-'` `. md5(``__FILE__``) .` `'.log'``;`

`if` `(``file_exists``(``$file``)) {`

`$contents` `= @``file_get_contents``(``$file``);`

`}` `else` `{`

`$contents` `=` `''``;`

`}`

`$contents` `.=` `$socket``->uid .` `"\n"``;`

`@``file_put_contents``(``$file``,` `$contents``);`

`if` `(!isset(``$last_online_count``[``$room``])) {`

`$last_online_count``[``$room``] = 0;`

`}`

`if` `(!isset(``$last_online_page_count``[``$room``])) {`

`$last_online_page_count``[``$room``] = 0;`

`}`

`// 将这个连接加入到uid分组,方便针对uid推送数据`

`$socket``->join(``$uid``);` `// 某个人`

`$socket``->join(``$socket``->uid);` `// 某个房间某个人`

`$socket``->join(``$room``);` `// 某个房间`

`$socket``->join(``$group``);` `// 分组,比如客服等`

`$socket``->to(``$room``)->emit(``'update_online_count'``,` `"当前{$last_online_count[$room]}人在线,共打开{$last_online_page_count[$room]}个页面"``);`

`});`

`// 当客户端断开连接是触发(一般是关闭网页或者跳转刷新导致)`

`$socket``->on(``'disconnect'``,` `function` `()` `use` `(``$socket``) {`

`if` `(!isset(``$socket``->uid)) {`

`return``;`

`}`

`global` `$uidConnectionMap``,` `$sender_io``,` `$socketIoPort``;`

`// 将uid的在线socket数减一`

`if` `(--``$uidConnectionMap``[``$socket``->uid] <= 0) {`

`unset(``$uidConnectionMap``[``$socket``->uid]);`

`}`

`// 从文件中删除`

`$file` `=` `'/tmp/logs/socket/'` `.` `$socketIoPort` `.` `'-'` `. md5(``__FILE__``) .` `'.log'``;`

`if` `(``file_exists``(``$file``)) {`

`$contents` `= @``file_get_contents``(``$file``);`

`if` `(``is_string``(``$contents``)) {`

`$arr` `=` `explode``(``"\n"``,` `$contents``);`

`foreach` `(``$arr` `as` `$k` `=>` `$v``) {`

`if` `(``$v` `==` `$socket``->uid) {`

`unset(``$arr``[``$k``]);`

`}`

`}`

`$contents` `= implode(``"\n"``,` `$arr``);`

`@``file_put_contents``(``$file``,` `$contents``);`

`}`

`}` `else` `{`

`$contents` `=` `''``;`

`}`

`@``file_put_contents``(``$file``,` `$contents``);`

`});`

`});`

`// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据`

`// to是追加的关系,比如->to(1)->to(2),那么会向1和2推送消息`

`$sender_io``->on(``'workerStart'``,` `function` `() {`

`// 监听一个http端口`

`$inner_http_worker` `=` `new` `Worker(``'http://0.0.0.0:2132'``);`

`// 当http客户端发来数据时触发`

`$inner_http_worker``->onMessage =` `function` `(``$http_connection``,` `$data``) {`

`/** @var \Workerman\Connection\TcpConnection $http_connection */`

`global` `$uidConnectionMap``;`

`$_POST` `=` `$_POST` `?` `$_POST` `:` `$_GET``;`

`$video_type` `=` `$_POST``[``'video_type'``] =  isset(``$_POST``[``'video_type'``]) ?` `$_POST``[``'video_type'``] :` `''``;`

`$video_id` `=` `$_POST``[``'video_id'``] = isset(``$_POST``[``'video_id'``]) ?` `$_POST``[``'video_id'``] :` `''``;`

`$room` `=` `$video_type` `.` `$video_id``;`

`// 推送数据的url格式 type=publish&to=uid&content=xxxx`

`require` `__DIR__ .` `'/logic.php'``;`

`return` `$http_connection``->send(``'fail'``);`

`};`

`// 执行监听`

`$inner_http_worker``->listen();`

`// 一个定时器,定时向所有uid推送当前uid在线数及在线页面数`

`Timer::add(1,` `function` `() {`

`global` `$uidConnectionMap``,` `$roomMap``,` `$sender_io``,` `$last_online_count``,` `$last_online_page_count``,` `$use_id``;`

`foreach` `(``$roomMap` `as` `$room` `=>` `$uids``) {`

`$online_count_now` `=` `count``(``$uids``);`

`$online_page_count_now` `=` `array_sum``(``$uids``);`

`// 只有在客户端在线数变化了才广播,减少不必要的客户端通讯`

`if` `(``$last_online_count``[``$room``] !=` `$online_count_now` `||` `$last_online_page_count``[``$room``] !=` `$online_page_count_now``) {`

`$sender_io``->to(``$room``)->emit(``'update_online_count'``,` `"当前{$online_count_now}人在线,共打开{$online_page_count_now}个页面"``);`

`$last_online_count``[``$room``] =` `$online_count_now``;`

`$last_online_page_count``[``$room``] =` `$online_page_count_now``;`

`}`

`}`

`});`

`});`

`if` `(!defined(``'GLOBAL_START'``)) {`

`Worker::runAll();`

`}`

 类似资料: