swool tcp mysql_Swoole WebSocket 实现mysql实时数据展示
最近在学习swoole,自己完成下论坛里留下的作业,通过swoole_websocket实时展示mysql数据,有个遗留问题,如何判断mysql是否有增删改,我想到的方法有:
1、在应用层中有增删改时,发一个消息到消息队列来监听。
2、解析mysql bin-log日志。
3、触发器。
现在的解决办法是利用触发器,例子中我只监听了一个表,当有多个表时,需要添加大量触发器,触发器本身占用很多资源,太多触发器也不好管理,之后会再想办法解析下bin-log日志来监听Mysql数据变化。
服务端代码
/**
* Created by PhpStorm.
* User: qyc
* Date: 2017/10/22
* Time: 下午4:40
*/
define('HOST', '0.0.0.0');
define('PORT', '9502');
define('WORKER_NUM', 8);
define('DISPATCH_MODE', 2);
define('DAEMONIZE', 0);
class swoole_ws
{
private $pdo;
private $server;
//这里写死了数据表,之后完成数据库监听后改写这里逻辑
private $table
= [
'swoole_test',
];
public function __construct()
{
$this->server = new swoole_websocket_server(HOST, PORT);
$this->server->set(
[
//开启woker进程数
'worker_num' => WORKER_NUM,
//请求分发策略,
'dispatch_mode' => DISPATCH_MODE,
//是否守护进程
'daemonize' => DAEMONIZE,
]
);
$this->server->on('message', [$this, 'onMessage']);
$this->server->on('open', [$this, 'onOpen']);
$this->server->on('workerStart', [$this, 'onWorkerStart']);
$this->server->start();
}
//woker进程
public function onWorkerStart(swoole_websocket_server $server, $worker_id)
{
if ($worker_id == 0) {
// 0 worker进程开启一个定时器去监听mysql数据变化
$this->server->tick(500, [$this, 'onTick']);
}
//每个worker进程维持一个pdo连接
$this->pdo = new PDO("mysql:host=localhost;dbname=swoole_ws", "root", "root");
}
//接受客户端数据
public function onMessage(swoole_websocket_server $server, swoole_websocket_frame $frame)
{
// echo $frame->data; //客户端发送的数据
// echo $server->worker_id;
}
//客户端 服务端建立连接并完成握手后的回调
public function onOpen(swoole_websocket_server $server, swoole_http_request $request)
{
//第一次连接去获取一下Mysql数据
$this->update();
}
private function update()
{
$res = [];
foreach ($this->table as $table) {
$res[$table] = $this->getTableData($table);
}
foreach ($this->server->connections as $connection) {
//向所有客户端发送数据
$this->server->push($connection, json_encode($res));
}
}
//获取表数据
private function getTableData($table)
{
$sql = 'select * from ' . $table;
try {
$stmt = $this->pdo->prepare($sql);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $res ?: [];
} catch (Exception $e) {
return [];
}
}
//定时器回调
public function onTick()
{
/*
* is_update表记录表是否更新过
* swoole_test表添加了3个触发器, after insert、update、delete,
* 会向is_update表更新swoole_test是否有更新操作
*/
try {
$sql = 'select is_update from is_update where table_name = "swoole_test"';
$stmt = $this->pdo->prepare($sql);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ( ! $res) {
return [];
}
if ($res[0]['is_update'] == 1) {
//当is_update字段为1时表明数据有更新,向客户端推送消息
$this->update();
//更新下表更新字段
$update = 'update is_update set is_update=0 where table_name = "swoole_test"';
$stmt = $this->pdo->prepare($update);
$stmt->execute();
}
} catch (Exception $e) {
$this->pdo = new PDO("mysql:host=localhost;dbname=swoole_ws", "root", "root");
}
}
}
new swoole_ws();
客户端代码
Mysql实时数据
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
crossorigin="anonymous">
swoole_test
var websocket = new WebSocket('ws://127.0.0.1:9502');
websocket.onopen = function (event) {
console.log('websocket connect');
websocket.send('hello swoole');
};
websocket.onclose = function (event) {
console.log('websocket close');
};
websocket.onerror = function (event, e) {
console.log('error occured:' + event.data);
};
websocket.onmessage = function (event) {
data = JSON.parse(event.data)['swoole_test'];
var th = '
';
var width = 1 / json_length(data[0]) * 100;
for (var key in data[0]) {
th += "
" + key + "";
}
th += '
';
$("#thead").html(th);
var tbody = '';
for (var line in data) {
tbody += '
';
var td = '';
for (var column in data[line]) {
td += "
" + data[line][column] + "";
}
tbody += td + '
';
}
$("#tbody").html(tbody);
};
function json_length(json) {
var length = 0;
for (var item in json) {
length++;
}
return length;
}
触发器
DELIMITER $$
/*更新触发器*/
DROP TRIGGER IF EXISTS swoole_test_is_update;
$$
CREATE TRIGGER swoole_test_is_update AFTER UPDATE ON swoole_test FOR EACH ROW
BEGIN
UPDATE `is_update`
SET is_update = 1
WHERE TABLE_NAME = 'swoole_test';
END;
$$
/*添加触发器*/
DROP TRIGGER IF EXISTS swoole_test_is_insert;
$$
CREATE TRIGGER swoole_test_is_insert AFTER UPDATE ON swoole_test FOR EACH ROW
BEGIN
UPDATE `is_update`
SET is_update = 1
WHERE TABLE_NAME = 'swoole_test';
END;
$$
/*删除触发器*/
DROP TRIGGER IF EXISTS swoole_test_is_delete;
$$
CREATE TRIGGER swoole_test_is_delete AFTER UPDATE ON swoole_test FOR EACH ROW
BEGIN
UPDATE `is_update`
SET is_update = 1
WHERE TABLE_NAME = 'swoole_test';
END;
$$
DELIMITER ;
开启websocker服务端
php swoole_ws;
运行效果
现在访问前端页面,对数据库进行增删改操作测试效果。
1.png
结语
这只是个swoole_websocket练习,熟悉一下,大家可以看看Swoole官方文档进行学习,会有不错的提升,之后会做个即时聊天工具玩玩,Just code for fun ~
swool tcp mysql_Swoole WebSocket 实现mysql实时数据展示相关推荐
- MySQL 到 MySQL 实时数据同步实操分享
摘要:很多 DBA 和开发同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.最近了解到一款实时数据同步工具 Tapdata C ...
- echarts 实时数据展示
echarts 实时数据展示 1. 构建一个web项目 完成从后台拉取MySQL的数据到前端的准备工作,我自己是用的ssm框架,这里是属于web的工作,不过多赘述. 2.先写一个简单的echart ...
- Oracle到MySQL实时数据同步CloudCanal实战
简述 CloudCanal 2.1.0.x 版本开始支持 Oracle 作为源端的数据迁移同步能力,目前邀请测试中. 本文通过 Oracle 到 MySQL 的数据迁移同步案例简要介绍这个源端的能力. ...
- swool tcp mysql_swoole/mysql(异步)
# 异步Swoole\Mysql **`(要求Workerman版本>=3.3.6)`** ## 注意: 此组件由swoole底层提供,由C语言编写,具有超高性能. ## 安装: ``` 安装有 ...
- mysql 取数据 展示_php mysql_fetch_row逐行获取结果集数据并显示在table表格中
在一般的网站中,我们会通常看到,很多数据库中表的数据在浏览器都是出现在表格中的,一开始让自己感到很神奇,但是仔细想想也不算太复杂,既然可以dql和dml的一般返回,以表格的方式返回应该也不成问题,但是 ...
- MySQL 到 MongoDB 实时数据同步实操分享
MySQL数据怎么实时同步到 MongoDB 实践分享系列 摘要:很多 DBA 同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同 ...
- MySQL 到 PostgreSQL 实时数据同步实操分享
摘要:很多 DBA 和开发同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.最近了解到一款实时数据同步工具 Tapdata C ...
- MySQL 到 SQL Server 实时数据同步实操分享
摘要:很多 DBA 和开发同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.最近了解到一款实时数据同步工具 Tapdata C ...
- python同花顺股票实时数据_web实时股票数据展示
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 所有这些都是实时发生的,并推送到仪表板供用户评估事物和行为. 最终,为了能够从任 ...
最新文章
- java swing中英文支持,java - Swing国际化 - 如何在运行时更新语言 - SO中文参考 - www.soinside.com...
- 在WINCE5.0中应用CMD(比如运行PING命令)
- 浙江农林大学2021年新生杯程序设计竞赛(同步赛)
- Debian Gnu/Linux 9关闭 111端口
- php面向对象的接口,PHP面向对象之接口编程
- mysql 动态创建事件_mysql 通过事件定时为数据库创建动态表名
- ie java 注册表,win7在桌面显示IE图标的注册表
- 单机数据库优化的一些实践
- 【Python】将xls格式转换为xlsx格式
- elasticserach(一)
- TM中拒收自定义表情的设置方法(转)
- 服务器修复oxc0000098,Win10系统无法开机0xc0000098错误怎么办_win10无法开机提示0xc0000098错误代码如何修复...
- 为什么选择高防DNS云解析?
- 2019年最新版,百度云不限速下载工具,亲测好用!
- 全面解析软文营销中的八大技巧
- 安装pycrypto
- Adobe Acrobat XI 安装版和免安装版_PDF转换软件
- 孙正义万字访谈实录:AI是我现在唯一关注的事情,我是科技的绝对信徒
- Vue - router vs route
- 将多个文件压缩成gzip,将gzip解压成多个文件
热门文章
- 最大乘积java_《算法入门经典》-最大乘积(java实现)
- Python高阶——argparse(命令行与参数解析)
- #Pragma Pack(n)与内存分配 pragma pack(push,1)与#pragma pack(1)的区别
- VC、VB、Delphi …… 你该学哪个?
- BZOJ4458: GTY的OJ
- spring data mongodb CURD
- java学习笔记(十一)常用类、反射、垃圾回收
- Struts tag-初体验
- mootools LightBox
- JSK-347 打印图形【打印图案】