Swoole实现Websocket推送
因为网上没有很具体的相关文档,只能摸着石头过河,现功能已经大致实现
<?php
$config = require('/config/swoole.php');
class Websocket {
public $server;
private $config;
public function __construct($config) {
$this->config = $config;
$server = new Swoole\WebSocket\Server($this->config['web_host'],$this->config['web_port']);
$this->server = $server;
$this->server->set([
'worker_num' => 8,
'daemonize' => 1,
'backlog' => 128,
'max_request' => 10000,
'heartbeat_check_interval' => 60,
'task_worker_num' => 24,
]);
$process = new Swoole\Process(function($process) use ($server) {
while (true) {
$show_market_list = $this->getRealMarket();
if ($show_market_list) {
foreach ($this->server->connections as $conn) {
$this->server->push($conn,json_encode(['type' => 'market','date' => $show_market_list]));
}
}
sleep(1);
}
});
$newprocess = new Swoole\Process(function($process) use ($server){
while (true) {
$redis = $this->newRedis();
$new_list = $redis->hGetALL('swoole_new_push');
if ($new_list) {
//把消息推给所有用户
foreach ($new_list as $k => $v) {
//查找用户的fd 检查用户是否在线
$user_fd = $redis -> hGet('swoole_uid_fd',$k);
if ($user_fd) {
$this->server->push($user_fd,json_encode(['type' => 'new','date' => $v]));
}
}
}
sleep(1);
}
});
$this->server->addProcess($newprocess);
$this->server->addProcess($process);
$this->server->on('handshake',function($request,$response){
$getAllMarket = $this->getAllMarket();
$this->server -> push($request->fd,json_encode($getAllMarket));
});
$this->server->on('open', function (swoole_websocket_server $server, $request) {
});
$this->server->on('task',function(swoole_server $server, $task_id, $from_id, $data){
$task = json_decode($data['type'],1);
switch ($task['type']) {
//K线
case 'kline':
$result['type'] = $task['type'];
$result['kline_time_type'] = $task['kline_time_type'];
$result['market'] = $task['market'];
$result['data'] = $this->getKlineDate($task['kline_time_type'],$task['market']);
$result['history'] = $this->getMarketRecord($task['market']);
$server -> push($data['fd'],json_encode($result));
break;
//用户注册
case 'login':
$token = $task['token'];
$redis = $this->newRedis();
$uid = $redis->hGet('user_token',$token);
if ($uid) {
//找到了 用户的uid
$redis -> hSet('swoole_uid_fd',$uid,$data['fd']);
$redis -> hSet('swoole_fd_uid',$data['fd'],$uid);
$result['type'] = 'login';
$result['code'] = 200;
}else{
$result['type'] = 'login';
$result['code'] = 400;
}
$server -> push($data['fd'],json_encode($result));
break;
//响应消息
case 'respond':
$token = $task['token'];
$redis = $this->newRedis();
$uid = $redis->hGet('user_token',$token);
if ($uid) {
$redis->hDel('swoole_new_push',$uid);
$result['type'] = 'respond';
$result['code'] = 200;
}else{
$result['type'] = 'respond';
$result['code'] = 400;
}
$server -> push($data['fd'],json_encode($result));
break;
default:
break;
}
});
$this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
$task['type'] = $frame->data;
$task['fd'] = $frame->fd;
$server -> task($task);
});
$this->server->on('close', function ($server, $fd) {
//删除用户在线
$redis = $this->newRedis();
$uid = $redis -> hGet('swoole_fd_uid',$fd);
if ($uid) {
$redis -> hDel('swoole_uid_fd',$uid);
$redis -> hDel('swoole_fd_uid',$fd);
}
});
$this->server->on('request', function ($request, $response) {
});
$this->server->start();
}
//K线数据
public function getKlineDate($type,$market){
$redis = $this->newRedis();
$date = $redis->hGet($type,$market);
return $date;
}
public function getMarketRecord($market){
$redis = $this->newRedis();
$result['yest_close_price'] = $redis->hget('yest_close_price',$market);
$result['today_open_price'] = $redis->hget('today_open_price',$market);
$result['today_low_price'] = $redis->hget('today_low_price',$market);
$result['today_high_price'] = $redis->hget('today_high_price',$market);
return $result;
}
//获取全部行情
public function getAllMarket(){
$redis = $this->newRedis();
$market_buy_list = $redis -> HgetAll('real_market_buy');
$market_sell_list = $redis -> HgetAll('real_market_sell');
$market_real_list = $redis->HgetAll('real_market');
foreach ($market_real_list as $k => $v) {
$show_market_list[$k]['real'] = $v;
$show_market_list[$k]['sell'] = $market_sell_list[$k];
$show_market_list[$k]['buy'] = $market_buy_list[$k];
}
return $show_market_list;
}
//获取变动的行情 进行广播
public function getRealMarket(){
$redis = $this->newRedis();
$market_buy_list = $redis -> HgetAll('real_market_buy');
$market_sell_list = $redis -> HgetAll('real_market_sell');
$market_real_list = $redis -> HgetAll('real_market');
foreach ($market_real_list as $k => $v) {
$result['real'] = $v;
$result['sell'] = $market_sell_list[$k];
$result['buy'] = $market_buy_list[$k];
$history_market = $redis -> hGet('history_market',$k);
if ($history_market == json_encode($result)) {
//这一次读取的数据 和历史数据是一样的
continue;
}else{
$show_market_list[$k] = $result;
}
}
return $show_market_list;
}
public function newRedis(){
$redis = new redis();
$redis -> connect($this->config['read_redis_host'],$this->config['read_redis_prot']);
$redis -> auth($this->config['read_redis_auth']);
return $redis;
}
}
new Websocket($config);
?>