You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
463 lines
22 KiB
463 lines
22 KiB
<?php
|
|
/**
|
|
* This file is part of workerman.
|
|
*
|
|
* Licensed under The MIT License
|
|
* For full copyright and license information, please see the MIT-LICENSE.txt
|
|
* Redistributions of files must retain the above copyright notice.
|
|
*
|
|
* @author walkor<walkor@workerman.net>
|
|
* @copyright walkor<walkor@workerman.net>
|
|
* @link http://www.workerman.net/
|
|
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
*/
|
|
|
|
/**
|
|
*可能存在的问题
|
|
* sendToClient 可能发送给不是当前房间的用户
|
|
*/
|
|
/**
|
|
* 聊天主逻辑
|
|
* 主要是处理 onMessage onClose
|
|
*/
|
|
use \GatewayWorker\Lib\Gateway;
|
|
use \GatewayWorker\Lib\Store;
|
|
use \GatewayWorker\Lib\Memcache;
|
|
use \Application\AdminClient;
|
|
use \Application\Crontab;
|
|
|
|
class Events
|
|
|
|
{
|
|
/**
|
|
* 有消息时
|
|
* @param int $client_id
|
|
* @param string $message
|
|
*/
|
|
public static function onMessage($client_id, $message)
|
|
{
|
|
// debug
|
|
// echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
|
|
|
|
// 客户端传递的是json数据
|
|
$message_data = json_decode($message, true);
|
|
if(!$message_data)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
if (empty($_SESSION) && strcmp($message_data['_method_'], 'login') !== 0) {
|
|
return ;
|
|
}
|
|
//判断是否有登录。
|
|
if (strcmp($message_data['_method_'], 'login') !== 0) {
|
|
if ($_SESSION['user_id'] == -1 && in_array($message_data['_method_'], array('SendPubMsg','SendPrvMsg','sendGift','Manage'))) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'请登录!')));
|
|
return ;
|
|
}
|
|
// 查看当前用户权限是否修改
|
|
$role = isset($_SESSION['role']) ? $_SESSION['role'] : null;
|
|
$action = AdminClient::checkUserRoleChanged($_SESSION['user_id'], $_SESSION['room_id'], $role);
|
|
if (!is_null($action)) {
|
|
if (in_array($action, array('addSysAdminer','removeSysAdminer'))) {
|
|
AdminClient::$action($_SESSION['room_id'], $_SESSION['user_id']);
|
|
} else if (in_array($action, array('adminer','removeAdminer'))) {
|
|
AdminClient::$action($_SESSION['room_id'], $_SESSION['user_id'], $client_id, $_SESSION['client_name'], true, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 根据类型执行不同的业务
|
|
switch($message_data['_method_'])
|
|
{
|
|
// 客户端回应服务端的心跳,代表在线。
|
|
case 'pong':
|
|
if (isset($_SESSION['room_id']) && isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) { //isset($message_data['device']) && strcmp($message_data['device'], 'android')
|
|
Crontab::setAnchorOnline($_SESSION['room_id'], $_SESSION['user_id']);
|
|
}
|
|
return;
|
|
// 客户端登录 message格式: {_method_ :login, name:xx, room_id:1} ,添加到客户端,广播给所有客户端xx进入聊天室
|
|
case 'logout':
|
|
// 从房间的客户端列表中删除
|
|
if(isset($_SESSION['room_id']))
|
|
{
|
|
$room_id = $_SESSION['room_id'];
|
|
$new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'user_id'=>$_SESSION['user_id'], 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
|
|
if (isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) {
|
|
$new_message['role'] = 'owner';
|
|
|
|
}
|
|
|
|
Gateway::unbindUid($client_id, $_SESSION['user_id']); //解除与uid的绑定。
|
|
Gateway::leaveGroup($client_id, $room_id); //离开当前的用户住,代表当前房间
|
|
Gateway::sendToGroup($room_id, json_encode($new_message)); //客户端断开连接需要执行此操作。
|
|
$_SESSION = array();
|
|
}
|
|
return ;
|
|
case 'login':
|
|
// 判断是否有房间号
|
|
if(!isset($message_data['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
$viewer = false;
|
|
if (!isset($message_data['user_name']) || !isset($message_data['user_id']) || $message_data['user_id'] <= 0 || $message_data['user_name'] == "") {
|
|
$viewer = true;
|
|
$message_data['user_name'] = '游客'.rand(10000,99999);
|
|
$message_data['user_id'] = -1;
|
|
$message_data['levelid'] = 0;
|
|
$message_data['ucuid'] = -1;
|
|
$message_data['vip'] = 0;
|
|
}
|
|
$client_name = htmlspecialchars($message_data['user_name']);
|
|
$room_id = $message_data['room_id'];
|
|
$user_id = $message_data['user_id'];
|
|
|
|
if (!$viewer) {
|
|
if (!AdminClient::isLogged($user_id, $message_data['token'])) {
|
|
// close this connection
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error' , 'content'=>'请先登录')));
|
|
Gateway::closeClient($client_id);
|
|
return;
|
|
}
|
|
}
|
|
|
|
$vip = $viewer ? 0 : AdminClient::hasVipPrivilete($user_id);
|
|
|
|
if ( $vip == 0 && AdminClient::isRoomFull($room_id)) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error.kicked','content'=>"非VIP用户不能进入满员房间~")));
|
|
// 延迟关闭连接
|
|
AdminClient::delayCloseClient(5,$client_id);
|
|
// Gateway::closeClient($client_id);
|
|
return;
|
|
}
|
|
|
|
$expire = 0;
|
|
$role = $viewer ? '' : AdminClient::getClientRole($room_id, $user_id, $expire);
|
|
if (!$vip &&strcmp($role, 'kicked') === 0 && $expire > time()) {
|
|
|
|
//TODO 关闭连接 已被踢出房间
|
|
$left = floor(($expire - time()) / 60);
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error.kicked','content'=>"您已被踢出房间, {$left}分钟后再进入房间")));
|
|
// 延迟关闭连接
|
|
AdminClient::delayCloseClient(5,$client_id);
|
|
// Gateway::closeClient($client_id);
|
|
return;
|
|
}
|
|
// 把房间号昵称放到session中
|
|
$isAdminer = false;
|
|
if (!is_null($role) && (strcmp($role, 'adminer') === 0 || strcmp($role, 'owner') === 0) || strcmp($role, 'sysAdminer') === 0) {
|
|
$_SESSION['role'] = $role;
|
|
if (strcmp($role, 'owner') === 0) {
|
|
AdminClient::setAnchorOnlie($user_id);
|
|
}
|
|
$isAdminer = true;
|
|
} else if (!$vip && !is_null($role) && strcmp($role, 'disableMsg') === 0) {
|
|
$_SESSION['disableMsg'] = 1;
|
|
$_SESSION['expire'] = $expire;
|
|
}
|
|
|
|
$ucuid = $message_data['ucuid'];
|
|
$_SESSION['client_name'] = $client_name;
|
|
$_SESSION['user_id'] = $user_id;
|
|
$_SESSION['room_id'] = $room_id;
|
|
$_SESSION['ucuid'] = $ucuid;
|
|
$_SESSION['client_id'] = $client_id;
|
|
$_SESSION['vip'] = $vip;
|
|
$_SESSION['levelid'] = $message_data['levelid'];
|
|
$_SESSION['time'] = 0;
|
|
$_SESSION['msged'] = false;
|
|
|
|
|
|
$new_message = array('type'=>$message_data['_method_'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'user_id'=>$user_id, 'ucuid'=>$ucuid,'vip'=>$vip,'levelid'=>$_SESSION['levelid'], 'time'=>date('H:i'));
|
|
$new_message['levelid'] = $message_data['levelid'];
|
|
if ($isAdminer) {
|
|
$new_message['role'] = 'adminer';
|
|
}
|
|
if (isset($message_data['daoju'])) {
|
|
$new_message['daoju'] = $message_data['daoju'];
|
|
}
|
|
|
|
// if ((strcmp($role, 'owner') !== 0)) {
|
|
// Gateway::sendToGroup($room_id, json_encode($new_message));
|
|
// }
|
|
Gateway::joinGroup($client_id, $room_id);
|
|
Gateway::bindUid($client_id, $user_id);
|
|
AdminClient::sendSysMsg($client_id, !isset($message_data['lang']) ? 'ch' : $message_data['lang']);
|
|
|
|
print_r($_SESSION);
|
|
// For APP
|
|
Crontab::sendOnLineList($room_id, $_SESSION);
|
|
print_r($new_message) ;
|
|
// For PC
|
|
Gateway::sendToCurrentClient(json_encode($new_message));
|
|
// Gateway::sendToGroup($room_id, json_encode($new_message));
|
|
return;
|
|
|
|
// 客户端发言 message: {_method_:SendPubMsg, to_client_id:xx, content:xx}
|
|
case 'LightHeart':
|
|
if(!isset($_SESSION['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
$new_message = array(
|
|
'type'=>'LightHeart',
|
|
'color'=> isset($message_data['color']) ? $message_data['color'] : 'red',
|
|
'client_id'=>$client_id,
|
|
'user_id'=>$_SESSION['user_id'],
|
|
'client_name'=>$_SESSION['client_name'],
|
|
'levelid'=>$_SESSION['levelid'],
|
|
'vip'=>$_SESSION['vip'],
|
|
'time'=>date('H:i'),
|
|
);
|
|
|
|
return Gateway::sendToGroup($_SESSION['room_id'], json_encode($new_message));
|
|
case 'SendPubMsg':
|
|
// 非法请求
|
|
if(!isset($_SESSION['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
if (trim($message_data['content']) == "") {
|
|
Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您不能发送空内容")));
|
|
return ;
|
|
}
|
|
// 是否可以发言
|
|
if (!AdminClient::isEnableMsg()) {
|
|
Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>"您已被管理员禁言")));
|
|
return ;
|
|
}
|
|
$msg = '';
|
|
if (!AdminClient::msgFrequency(strlen($message_data['content']), $msg)) {
|
|
Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>$msg)));
|
|
return ;
|
|
}
|
|
$room_id = $_SESSION['room_id'];
|
|
$client_name = $_SESSION['client_name'];
|
|
|
|
|
|
$new_message = array(
|
|
'type'=>'SendPubMsg',
|
|
'from_user_id'=>$_SESSION['user_id'],
|
|
'from_client_name' =>$client_name,
|
|
'vip'=>$_SESSION['vip'],
|
|
'levelid'=>$_SESSION['levelid'],
|
|
'avatar'=>AdminClient::getAvatar($_SESSION['user_id']),
|
|
// 'to_client_id'=>'all',
|
|
'content'=>nl2br(htmlspecialchars(AdminClient::filter($message_data['content']))),
|
|
'time'=>date('H:i'),
|
|
);
|
|
// 飞屏特效
|
|
$new_message['fly'] = isset($message_data['fly']) ? $message_data['fly'] : '';
|
|
|
|
return Gateway::sendToGroup($room_id ,json_encode($new_message));
|
|
case 'SendPrvMsg':
|
|
// 非法请求
|
|
if(!isset($_SESSION['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
if (trim($message_data['content']) == "") {
|
|
Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您不能发送空内容")));
|
|
return ;
|
|
}
|
|
// 是否可以发言
|
|
if (!AdminClient::isEnableMsg()) {
|
|
Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您已被管理员禁言")));
|
|
return ;
|
|
}
|
|
if (!AdminClient::ablePriMsg()){
|
|
Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"富豪等级3以下不能发私信,快快升级吧")));
|
|
return ;
|
|
}
|
|
$msg = '';
|
|
if (!AdminClient::msgFrequency(strlen($message_data['content']), $msg)) {
|
|
Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>$msg)));
|
|
return ;
|
|
}
|
|
|
|
$room_id = $_SESSION['room_id'];
|
|
$client_name = $_SESSION['client_name'];
|
|
|
|
// 私聊
|
|
$new_message = array(
|
|
'type'=>'SendPrvMsg',
|
|
'from_user_id'=>$_SESSION['user_id'],
|
|
'from_client_name' =>$client_name,
|
|
'vip'=>$_SESSION['vip'],
|
|
'levelid'=>$_SESSION['levelid'],
|
|
'avatar'=> AdminClient::getAvatar($_SESSION['user_id']),
|
|
'to_client_name'=>$message_data['to_client_name'],
|
|
'to_user_id'=>isset($message_data['to_user_id']) ? $message_data['to_user_id'] : 0,
|
|
'pub'=>$message_data['pub'],
|
|
'content'=>nl2br(htmlspecialchars(AdminClient::filter($message_data['content']))),
|
|
'time'=>date('H:i'),
|
|
);
|
|
// 飞屏特效
|
|
// $new_message['fly'] = isset($message_data['fly']) ? $message_data['fly'] : '';
|
|
|
|
//可公开的私聊
|
|
if ($message_data['pub']) {
|
|
return Gateway::sendToGroup($room_id ,json_encode($new_message));
|
|
} else {
|
|
//私密聊天,不公开
|
|
Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
|
|
// $new_message['content'] = nl2br(htmlspecialchars($message_data['content']));
|
|
return Gateway::sendToCurrentClient(json_encode($new_message));
|
|
}
|
|
case 'vodSong':
|
|
if (!isset($message_data['songName'])) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'请填写歌曲!')));
|
|
return ;
|
|
}
|
|
if ($_SESSION['user_id'] == -1) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'游客不能点歌!')));
|
|
return ;
|
|
}
|
|
$new_message = array('type'=>'vodSong');
|
|
return Gateway::sendToGroup($_SESSION['room_id'] ,json_encode($new_message));
|
|
case 'setBackground':
|
|
case 'cancelBackground':
|
|
$error = "";
|
|
$new_message = array();
|
|
if (!isset($_SESSION['role']) || !in_array($_SESSION['role'],array('owner','sysAdminer'))) {
|
|
$error = "您不是房主或系统管理员";
|
|
}
|
|
if ( strcmp($message_data['_method_'],'setBackground') == 0 && (!isset($message_data['bgimg']) || $message_data['bgimg'] == "")) {
|
|
$error = "参数错误,请稍后尝试...";
|
|
}
|
|
if ($error != "") {
|
|
return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>$error)));
|
|
}
|
|
return Gateway::sendToGroup($_SESSION['room_id'], json_encode(array('type'=>$message_data['_method_'],'bgimg'=>$message_data['bgimg'])));
|
|
case 'setSongApply':
|
|
if (!isset($_SESSION['role']) || strcmp($_SESSION['role'],'owner') != 0) {
|
|
return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您不是房主哦!')));
|
|
}
|
|
if (!isset($message_data['apply'])) {
|
|
return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'参数错误')));
|
|
}
|
|
return Gateway::sendToGroup($_SESSION['room_id'],json_encode(array('type'=>'setSongApply','apply'=>$message_data['apply'])));
|
|
case 'disAgreeSong':
|
|
case 'agreeSong':
|
|
if (!isset($_SESSION['role']) || strcmp($_SESSION['role'], 'owner') !== 0) {
|
|
// 当前用户不在该房间
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您不是房主哦!')));
|
|
return ;
|
|
}
|
|
$new_message = array('type'=>$message_data['_method_']);
|
|
if ($message_data['_method_'] == 'agreeSong') {
|
|
$new_message['client_name'] = $message_data['userName'];
|
|
$new_message['songName'] = $message_data['songName'];
|
|
}
|
|
return Gateway::sendToGroup($_SESSION['room_id'],json_encode($new_message));
|
|
case 'sendGift':
|
|
// 此接口已废弃
|
|
// Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'此接口已废弃')));
|
|
// return ;
|
|
|
|
// 非法请求
|
|
if(!isset($_SESSION['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
$room_id = $_SESSION['room_id'];
|
|
$client_name = $_SESSION['client_name'];
|
|
|
|
// 防止别人冒名发消息
|
|
if (strcmp($client_name, $message_data['userName']) !== 0) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'不能冒名发送礼物')));
|
|
return ;
|
|
}
|
|
|
|
unset($message_data['_method_']);
|
|
unset($message_data['userName']);
|
|
$message_data['from_client_name'] = $client_name;
|
|
$message_data['type'] = 'sendGift';
|
|
$message_data['code'] = 0;
|
|
$message_data['time'] = date('H:i');
|
|
$new_message = $message_data;
|
|
$new_message['from_client_id'] = $client_id;
|
|
$new_message['from_user_id'] = $_SESSION['user_id'];
|
|
$new_message['vip'] = $_SESSION['vip'];
|
|
$new_message['levelid'] = $_SESSION['levelid'];
|
|
|
|
return Gateway::sendToGroup($room_id ,json_encode($new_message));
|
|
case 'Manage':
|
|
// 非法请求
|
|
if(!isset($_SESSION['room_id']))
|
|
{
|
|
return;
|
|
}
|
|
// 是否有管理员权限
|
|
if (!isset($_SESSION['role']) || !in_array($_SESSION['role'], array('adminer','owner','sysAdminer'))) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您没有管理员权限')));
|
|
return;
|
|
}
|
|
|
|
$room_id = $_SESSION['room_id'];
|
|
$client_name = $_SESSION['client_name'];
|
|
|
|
$managed_user_id = $message_data['managed_user_id'];
|
|
// $managed_client_id = $message_data['managed_client_id'];
|
|
// $uidToClientArray = Gateway::getClientIdByUid($managed_user_id);
|
|
// $managed_client_id = array_shift($uidToClientArray);
|
|
$managed_client_id_array = Gateway::getClientIdByUid($managed_user_id);
|
|
$managed_user_name = $message_data['managed_user_name'];
|
|
$type = $message_data['_type_'];
|
|
if ( $managed_user_id == -1 && in_array($type, array('adminer','removeAdminer'))) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'无法对游客做此操作!')));
|
|
return ;
|
|
}
|
|
|
|
// if (!Gateway::isUidOnline($managed_user_id)) {
|
|
// // 当前用户不在该房间
|
|
// Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'当前用户不在该房间')));
|
|
// return ;
|
|
// }
|
|
|
|
if (in_array($type, array('adminer','removeAdminer','addKicked','removeKicked','disableMsg','enableMsg'))) {
|
|
if ( $managed_user_id == -1 && in_array($type, array(array('adminer','removeAdminer')))) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'无法对游客做此操作!')));
|
|
return ;
|
|
}
|
|
// 查看VIP状态
|
|
if (in_array($type, array('addKicked','disableMsg')) && AdminClient::hasVipPrivilete($managed_user_id)) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'该用户为 VIP 会员,操作失败!')));
|
|
return ;
|
|
}
|
|
if (!AdminClient::ableToManage($managed_user_id, $room_id)) {
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'无法操作管理员')));
|
|
return;
|
|
}
|
|
Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'操作成功!')));
|
|
AdminClient::$type($room_id, $managed_user_id, $managed_client_id_array, $managed_user_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 当客户端断开连接时
|
|
* @param integer $client_id 客户端id
|
|
*/
|
|
public static function onClose($client_id)
|
|
{
|
|
// debug
|
|
// echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id onClose:''\n";
|
|
|
|
// 从房间的客户端列表中删除
|
|
if(isset($_SESSION['room_id']))
|
|
{
|
|
/*
|
|
if (isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) {
|
|
Crontab::delAnchorOnline($_SESSION['room_id']);
|
|
AdminClient::setAnchorOffLine($_SESSION['user_id']);
|
|
}
|
|
*/
|
|
$room_id = $_SESSION['room_id'];
|
|
$new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'user_id'=>$_SESSION['user_id'], 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
|
|
Gateway::sendToGroup($room_id, json_encode($new_message));
|
|
}
|
|
}
|
|
}
|
|
|