Redis sub / pub和php / nodejs

时间:2011-07-31 18:14:11

标签: php mysql node.js redis

使用redis作为子/ pub系统开始处理新项目以显示mysql db的结果。因此,如果有更新,我想将这些更新从mysql发布到我的网页。我的问题是,哪个选项更好?

选项1: 我应该通过nodejs和socket.io来完成所有这些工作吗?意思是创建连接到redis的nodejs脚本,订阅我需要监听的通道,使用nodejs中的mysql查询db for updates,如果更新发布mysql行,则通过socket.io获取连接到nodejs的html新数据并处理它以显示结果?

选项2: 有一个PHP脚本查询mysql和redis-php客户端发布任何更新到该频道?不知道还有什么需要从这里设置。我是否还需要在此选项中使用nodej?

或者我刚刚根据这一切是如何工作的?最重要的是我想通过mysql数据库向用户显示使用redis sub / pub功能的结果。

1 个答案:

答案 0 :(得分:24)

选项3

当您从PHP更新MySQL时,您可以通过redis publish命令将这些更改发布到node.js(在更改数据库时从PHP发布)。从node.js开始,由于Redis的订阅,我会实时收到这些更改。然后我会通过socket.io将它们广播给感兴趣的用户。例如,publish可以引导mysql。以下面的SQL语句=>为例INSERT INTO comments (1, "Hello World")。其中1类似于userid,Hello World类似于评论。我可能不会将SQL语句发布到该通道,但我可以轻松地使用JSON(JSON.stringify / JSON.parse)和PHP(json_encode / json_decode)。

更新

你没有运行cron-job,因为这会破坏Redis的pubsub的目的。例如,我访问您的网站http://localhosts上的博客。我在http://localhost.com/a.php读了一篇文章。在网站下方,您提供了一个表单,我可以用它来发表对该文章的评论:

<强> a.php只会

<html>
<head>
    <title>Interesting blog post</title>
</head>
<body>
    <div id="article">This is interesting</div>

    <div id="comments">
        <div class="comment">
            <div class="from">Alfred Said at 22:34</div>
            <div class="message">Hello World</div>
        </div>
    </div>

    <form action="post.php" method="post">
        <label for="name">Your name</label><br />
        <input type="name" id="name" name="name" /><br />

        <label for="message">Your Message:</label><br />
        <textarea id="message" name="message"></textarea>

        <input type="submit" />
    </form>


    <script src='jquery.min.js'></script>
    <script src='http://localhost:8888/socket.io/socket.io.js'></script>
    <script type="text/javascript">
        $(document).ready(function () {
                var socket = io.connect('http://localhost:8888');

                socket.on('message', function (json) {
                    var obj = $.parseJSON(json);
                    alert('in here: ' + obj.name);
                });
        });
    </script>
</body>
</html>

我提交了包含操作属性http://localhost/postcomment.php的表单。但这是重要的一部分!在post.php,您检索我发布的数据,并使用INSERT INTO comments (1, "Hello World")将其插入MySQL。当发生此突变时,您还需要通知node.js进程,该进程不断收听通道mysql

<强> post.php中:

<?php

$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

require("./Predis.php");
$redis = new Predis\Client();
$obj = array(
    'name'      => $_POST['name'],
    'message'   => $_POST['message']
);

$json = json_encode($obj);
$redis->publish("mysql", $json);

echo $json;

post.php 需要predis

node_redis的节点代码如下所示:

var redis       = require('redis'),
    subscriber  = redis.createClient(),
    express     = require('express'),
    store       = new express.session.MemoryStore(),
    app         = express.createServer(
        express.bodyParser(),
        express.static(__dirname + '/public'),
        express.cookieParser(),
        express.session({ secret: 'htuayreve', store: store}))
    sio         = require('socket.io');

app.listen(8888, '127.0.0.1',  function () {
    var addr = app.address();
    console.log('app listening on http://' + addr.address + ':' + addr.port);
});

var io = sio.listen(app);

io.configure(function () {
    io.set('log level', 1); // reduce logging
});

io.sockets.on('connection', function (socket) {
    socket.join('mysql');   
    socket.on('disconnect', function () {
    });
});

subscriber.on('message', function (channel, json) {
    // this will always retrieve messages posted to mysql
    io.sockets.in('mysql').json.send(json);
});

subscriber.subscribe('mysql');

此示例取决于您可以通过npm

安装的以下软件包
npm install socket.io
npm install redis
npm install express

当我发布表单post.php时,我也会将这些更改发布到redis。这部分很重要!由于Redis的pubsub,node.js进程总是接收这些更改。每当php脚本改变数据库时,您应该使用publish将这些更改发布到Redis。

P.S:希望这很清楚。也许以后当我有一些时间可用时,我会用可能的小片段进行更新...