先看一个代码的结构图:
也许熟悉TP5.1的小伙伴们看出来了,没错,这里面演示的就是在Tp5.0中的调用
先是关键核心的Http.php文件:
ws=new \swoole_websocket_server(self::HOST,self::PORT,SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$this->ws = new \swoole_websocket_server(self::HOST, self::PORT);
$this->ws->set([
//心跳检测
'heartbeat_check_interval' => 60,
'heartbeat_idle_time' => 600,
//设置证书,实现wss连接
// 'ssl_cert_file' => $this->pwd.'pai.wanguo.net.crt',
// 'ssl_key_file' => $this->pwd.'pai.wanguo.net.key',
]);
//监听新端口
$this->client = $this->ws->listen("127.0.0.1", 12317, SWOOLE_SOCK_TCP);
//关闭websocket模式
$this->client->set([
'open_websocket_protocol' => false,
]);
$this->ws->on("start", [$this, 'onStart']);
$this->client->on("receive", [$this, 'onReceive']);
$this->ws->on('message', [$this, 'onmessage']);
$this->ws->on('close', [$this, 'onclose']);
$this->client->on('close', [$this, 'oncloses']);
$this->ws->start();
}
//监听数据接收事件
public function onReceive($serv, $fd, $from_id, $data)
{
$data = json_decode($data, true);
//成交
if ($data['type'] == 'done') {
self::push_room($data['room_id'],$data);
$data['tips']=$room_id."已成交,最终成交价格:¥".$price."元";
//推送全部
self::push_all($data);
}elseif ($data['type'] == 'msg') {
//个人
if ($data['totype']=='single') {
unset($data['totype']);
$id=$data["toid"];
unset($data['toid']);
self::push_single($id,$data);
//房间
}elseif ($data['totype']=='room') {
unset($data['totype']);
$id=$data["toid"];
unset($data['toid']);
self::push_room($id,$data);
//全部
}elseif ($data['totype']=='all'){
unset($data['totype']);
unset($data['toid']);
self::push_all($data);
}
}else{
//出价 开始 结束
self::push_room($data['room_id'],$data);
//结束的时候清除对应redis
if ($data['type'] == 'end') {
$push_arr=Predis::getInstance()->smembers('room_id'.$data['room_id']);
//获取该房间下用户的fd
$fds=[];
foreach ($push_arr as $v) {
$fds=Predis::getInstance()->smembers(substr($v,6)); //smembers自动写入,所以要截取掉
foreach ($fds as $vv) {
Predis::getInstance()->del(substr($vv,6)); //删除在线的fd字符
}
Predis::getInstance()->del(substr($v,6)); //删除在线的用户
}
Predis::getInstance()->del('room_id'.$data['room_id']); //对应的价格
Predis::getInstance()->hdel('new_price',$data['room_id']); //对应的价格
}
}
}
/**
* 推送房间所有人
* $room_id 当前房间id
* $arr 组装数据
*/
public function push_room($room_id, $arr)
{
//获取该房间下的用户
$push_arr = Predis::getInstance()->smembers('room_id' . $room_id);
//获取该房间下用户的fd
$fds = [];
foreach ($push_arr as $k => $v) {
$fds = Predis::getInstance()->smembers(substr($v, 6)); //smembers自动写入,所以要截取掉
foreach ($fds as $vv) {
//推送
$this->ws->push(substr($vv, 8), json_encode($arr));
}
}
}
/**
* 推送消息给所有人
* $arr 通知的消息
*/
public function push_all($arr)
{
//获取所有人的fd
$fd=Predis::getInstance()->keys("fd*");
foreach ($fd as $k => $v) {
$v=str_replace("paiv3_fd","",$v);
$this->ws->push($v, json_encode($arr));
}
}
/**
* 推送给个人
* $arr 通知的消息
*
*/
public function push_single($id,$arr)
{
$fds=Predis::getInstance()->keys("fd*");
foreach ($fds as $k => $v) {
//解析fd下的uid信息
$user=json_decode(Predis::getInstance()->gets($v), true);
//判断所有uid的fd连接
if ($user['uid'] == $id) {
$fd[]=str_replace("paiv3_fd","",$v);
}
}
foreach ($fd as $v) {
$this->ws->push($v, json_encode($arr));
}
}
/**
* 设置进程名,为后续平滑重启进程
* @param $server
*/
public function onStart($server)
{
swoole_set_process_name("live_master");
}
/**
* 监听接收事件的回调
*/
public function onmessage($server, $frame)
{
//在接收数据的时候进行推送
$data = json_decode($frame->data, true);
if (empty($data["room_id"]) || empty($data["uid"])) {
return flase;
}
//加入组集合(集合)
Predis::getInstance()->sadd('group', $data['room_id']);
//加入分组(集合)
Predis::getInstance()->sadd('room_id' . $data['room_id'], 'room_id' . $data['room_id'] . '_' . $data['uid']);
//加入会员fd的集合(集合)
Predis::getInstance()->sadd('room_id' . $data['room_id'] . '_' . $data['uid'], 'fd' . $frame->fd);
//创建fd的json数据(字符)
$json['room_id'] = $data['room_id'];
$json['uid'] = $data['uid'];
Predis::getInstance()->set('fd' . $frame->fd, json_encode($json));
//组装发送的数据
$arr['name'] = $data['name'];
$arr['uid'] = $data['uid'];
$arr['type'] = "join";
$arr['num'] = Predis::getInstance()->scard('room_id' . $data['room_id']);
//推送
self::push_room($data['room_id'], $arr);
}
/**
* 监听关闭事件的回调
*/
public function onclose($ser, $fd)
{
//先获取字符fd,并得到room_id和uid
$data = json_decode(Predis::getInstance()->get('fd' . $fd), true);
//删除用户该次的fd
Predis::getInstance()->srem('room_id' . $data['room_id'] . '_' . $data['uid'], 'fd' . $fd);
//删除字段
Predis::getInstance()->del('fd' . $fd);
//判断是否为空
if (empty(Predis::getInstance()->smembers('room_id' . $data['room_id'] . '_' . $data['uid']))) {
//删除该用户的uid
Predis::getInstance()->del('room_id' . $data['room_id'] . '_' . $data['uid']);
//删除分组里面该用户信息
Predis::getInstance()->srem('room_id' . $data['room_id'], 'room_id' . $data['room_id'] . '_' . $data['uid']);
//本地房间推送
$arr['type']='offline';
$arr['num']=Predis::getInstance()->scard('room_id' . $data['room_id']);
self::push_room($data['room_id'],$arr);
}
}
public function oncloses($ser, $fd)
{
}
}
new Http();
然后是Predis.php
redis = new \Redis();
$result = $this->redis->connect('127.0.0.1',6379);
if($result === false) {
throw new \Exception('redis connect error');
}
}
/**
* set
* @param $key
* @param $value
* @param int $time
* @return bool|string
*/
public function set($key, $value, $time = 0 ) {
if(!$key) {
return '';
}
if(is_array($value)) {
$value = json_encode($value);
}
if(!$time) {
return $this->redis->set($this->redis_fix.$key, $value);
}
return $this->redis->setex($this->redis_fix.$key, $time, $value);
}
/**
* get
* @param $key
* @return bool|string
*/
public function get($key) {
if(!$key) {
return '';
}
return $this->redis->get($this->redis_fix.$key);
}
public function gets($key)
{
return $this->redis->get($key);
}
/**
* @param $key
* @return array
*/
public function smembers($key) {
return $this->redis->sMembers($this->redis_fix.$key);
}
public function srem($key,$valus) {
return $this->redis->sRem($this->redis_fix.$key,$this->redis_fix.$valus);
}
public function scard($key) {
return $this->redis->sCard($this->redis_fix.$key);
}
public function lpush($key,$date)
{
return $this->redis->lpush($this->redis_fix.$key,$date);
}
public function lrange($key,$start,$end)
{
return $this->redis->lrange($this->redis_fix.$key,$start,$end);
}
public function del($key)
{
return $this->redis->del($this->redis_fix.$key);
}
public function incr($key)
{
return $this->redis->incr($this->redis_fix.$key);
}
public function llen($key)
{
return $this->redis->llen($this->redis_fix.$key);
}
public function lpop($key)
{
return $this->redis->lpop($this->redis_fix.$key);
}
public function sadd($key,$val)
{
return $this->redis->sadd($this->redis_fix.$key,$this->redis_fix.$val);
}
//hash
public function hset($key,$name,$val)
{
return $this->redis->hset($this->redis_fix.$key,$this->redis_fix.$name,$val);
}
public function hexists($key,$name)
{
return $this->redis->hexists($this->redis_fix.$key,$this->redis_fix.$name);
}
public function hgetall($key)
{
return $this->redis->hgetall($this->redis_fix.$key);
}
public function hget($key,$filed)
{
return $this->redis->hget($this->redis_fix.$key,$this->redis_fix.$filed);
}
public function hvals($key)
{
return $this->redis->hvals($this->redis_fix.$key);
}
public function hdel($key,$name)
{
return $this->redis->hdel($this->redis_fix.$key,$this->redis_fix.$name);
}
public function keys($key)
{
return $this->redis->keys($this->redis_fix.$key);
}
/**
* @param $name
* @param $arguments
* @return array
*/
public function __call($name, $arguments) {
//echo $name.PHP_EOL;
//print_r($arguments);
if(count($arguments) != 2) {
return '';
}
$this->redis->$name($arguments[0], $arguments[1]);
}
}
最后也就是引入的类库Socket6.php
connect('127.0.0.1', 12317);
if (empty($res)) {
return "连接失败";
}else{
$cli->send($data);
}
}
}
写到了这里,当点swoole的都知道了,只要在cli中执行php Http.php & 命令就可以了,
完后在TP的常规文件中,执行我们Socket6类中的命令就可以了;
比如说:
大家可以简单看一下,不过话说我要是写golang也这么的写,会被打死的``````