多线程用Channel通讯
- 开启Channel服务
new \Channel\Server('127.0.0.1',2206);
- 在onWorkerStart()中链接Channel服务并注册事件
\Channel\Client::connect('127.0.0.1',2206);
$event_name = '事件名称';
\Channel\Client::on($event_name,function($event_data){
});
\Channel\Client::publish($event_name,$data);
<?php
namespace app\http\controller;
use think\worker\Server;
use \Workerman\Lib\Timer;
use app\common\library\Auth;
use app\common\library\Token;
use app\common\model\Message;
use \Channel\Client;
class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:9503';
protected $uidConnections = [];
protected $uidConnectionIds = [];
protected $HEARTBEAT_TIME = '300';
protected $auth;
protected $redis;
protected $config;
protected $worker;
protected $option = [
'name' => 'worker name',
'count' => 4,
'transport' => 'ssl'
];
public function onMessage($connection, $data)
{
try {
$data = json_decode($data, true);
$type = @$data['type'];
if ($type != 'admin') {
if (!isset($data['socket_id']) || empty($data['socket_id'])) {
$connection->close($this->error());
} else {
if ($this->auth->init($data['socket_id']) == false) {
$connection->close($this->error());
}
$uid = $this->redis->get($data['socket_id']);
if (empty($uid)) {
$connection->close($this->error());
}
if (isset($this->uidConnections[$uid])) {
$a = $this->uidConnections[$uid];
if ($a->id != $connection->id) {
$a->close($this->error('您已在其他地方登录!'));
}
}
}
switch ($type) {
case 'register':
$uidConnections = $this->uidConnections;
$uidConnections[$uid] = $connection;
$this->uidConnections = $uidConnections;
$uidConnectionIds = $this->uidConnectionIds;
$uidConnectionIds[$connection->id] = $uid;
$this->uidConnectionIds = $uidConnectionIds;
$this->redis->zAdd($this->config['prefix'] . 'socketOnline', true, $uid);
$connection->send($this->success(['message' => '通讯成功'], '通讯成功!'));
$this->history($uid);
break;
case 'ping':
$connection->send($this->pong($uid));
break;
default:
$connection->send($this->error());
break;
}
}
} catch (\Exception $e) {
echo $e->getMessage() . "\r\n";
}
}
public function onWorkerStart($worker)
{
\Channel\Client::connect('127.0.0.1', 2206);
$_this = $this;
\Channel\Client::on('Findandforward', function ($event_data) use ($worker, $_this) {
$type = $event_data['type'];
switch ($type) {
case 'Message':
$messageModel = new \app\common\model\Message();
if (isset($event_data['uid']) && $event_data['uid'] > 0) {
echo "给指定会员推送:" . $event_data['uid'] . "\r\n";
if (isset($_this->uidConnections) && is_array($_this->uidConnections)) {
if (isset($_this->uidConnections[$event_data['uid']])) {
echo $event_data['uid'] . "\r\n";
$result = $messageModel->getNoReadMessageNum2($event_data['uid']);
$_this->uidConnections[$event_data['uid']]->send($_this->success($result, 'newMessage'));
}
}
} else {
echo '给所有人广播' . "\r\n";
if (isset($_this->uidConnections) && is_array($_this->uidConnections)) {
foreach ($_this->uidConnections as $k => $v) {
$result = $messageModel->getNoReadMessageNum2($k);
var_dump($k);
$v->send($_this->success($result, 'newMessage'));
}
}
}
break;
}
});
\Channel\Client::on('Findandclose', function ($event_data) use ($worker, $_this) {
$connectionId = $event_data['connecttion_id'];
if (isset($_this->uidConnectionIds[$connectionId])) {
$uid = $_this->uidConnectionIds[$connectionId];
unset($_this->uidConnectionIds[$connectionId]);
unset($_this->uidConnections[$uid]);
}
});
try {
$this->auth = Auth::instance();
$config = getRedis(1);
$redis = $config['redis'];
$this->config = $config;
$this->redis = $redis;
$inner_text_worker = new \Workerman\Worker('Text://127.0.0.1:7755');
$inner_text_worker->onMessage = function ($connection, $buffer) {
$buffer = json_decode($buffer, true);
switch ($buffer['type']) {
case 'newMessage':
$uid = $buffer['uid'];
\Channel\Client::publish('Findandforward', ['type' => 'Message', 'uid' => $uid]);
break;
case 'systemMessageToChange':
\Channel\Client::publish('Findandforward', ['type' => 'Message']);
break;
default:
$connection->send(false);
break;
}
$connection->send('success');
};
$inner_text_worker->listen();
} catch (\Exception $e) {
echo $e->getMessage() . "\r\n";
}
}
public function onClose($connection)
{
try {
$id = $connection->id;
if (isset($this->uidConnectionIds[$id])) {
$uid = $this->uidConnectionIds[$id];
unset($this->uidConnectionIds[$id]);
unset($this->uidConnections[$uid]);
$this->redis->zRem($this->config['prefix'] . 'socketOnline', $uid);
} else {
\Channel\Client::publish('Findandclose', ['connecttion_id' => $id]);
}
} catch (\Exception $e) {
}
}
public function history($uid)
{
$connection = $this->uidConnections[$uid];
if ($connection) {
$userModel = new \app\common\model\User();
$user = $userModel->get($uid);
if ($user) {
$messageModel = new \app\common\model\Message();
$result = $messageModel->getNoReadMessageNum($user['id'], $user['is_redmom']);
$this->sendMessageByUid($result, $uid, 'newMessage');
}
}
}
public function sendMessageByUid($data = [], $uid = '', $type = 'success', $uidConnections = [])
{
$uidConnections = $this->uidConnections;
if (isset($uidConnections[$uid]) && !empty($uidConnections[$uid])) {
$uidConnections[$uid]->send($this->success($data, $type));
}
}
public function send($data = [], $uid = '')
{
foreach ($this->uidConnections as $k => $v) {
if (!empty($uid) && $uid == $k) {
$v->send($this->success($data));
} else if (empty($uid)) {
$v->send($this->success($data));
}
}
}
public function error($msg = '通讯异常, 参数错误!')
{
return json_encode(array('msg' => $msg, 'type' => 'error', 'time' => date('Y-m-d H:i:s')), JSON_UNESCAPED_UNICODE);
}
public function success($data = [], $type = "success", $msg = 'success')
{
return json_encode(array('data' => $data, 'msg' => $msg, 'type' => $type, 'time' => date('Y-m-d H:i:s')), JSON_UNESCAPED_UNICODE);
}
public function pong($data = [])
{
return json_encode(array('data' => $data, 'msg' => '心跳', 'type' => 'pong', 'online' => count($this->uidConnections), 'time' => date('Y-m-d H:i:s')), JSON_UNESCAPED_UNICODE);
}
}