Redis sub / pub и php / nodejs - PullRequest
       21

Redis sub / pub и php / nodejs

11 голосов
/ 31 июля 2011

Начало работы над новым проектом с использованием redis в качестве системы sub / pub для отображения результатов из базы данных mysql. Так что, если есть обновления, я хотел бы опубликовать эти обновления из MySQL на моей веб-странице. У меня вопрос, какой вариант будет лучше?

Вариант 1: Должен ли я просто сделать все это через nodejs и socket.io? Это означает создание сценария nodejs, который подключается к redis, подписывается на каналы, которые мне нужно прослушивать, используя mysql в nodejs, запрашивает базу данных об обновлениях, если обновления публикуют строки mysql, а затем в html, который подключается к nodejs через socket.io get новые данные и обработать их для отображения результатов?

Вариант 2: Есть ли у php-скрипта запрос mysql и с помощью клиента redis-php публиковать какие-либо обновления канала? Не знаю точно, что еще нужно настроить здесь. Нужно ли мне включать nodejs в эту опцию?

Или я просто не знаю, как все это работает? Суть в том, что я хочу отображать результаты через базу данных mysql пользователю, используя возможности redis sub / pub.

1 Ответ

24 голосов
/ 01 августа 2011

Опция 3

Когда вы обновляете MySQL из PHP, вы публикуете эти изменения в node.js с помощью команды redis publish (публикация из PHP при изменении базы данных).Из node.js я получил бы эти изменения в режиме реального времени благодаря подписке Redis.Тогда я бы просто передавал их пользователям, заинтересованным через socket.io.Вы можете, например, publish на канал mysql.Возьмем для примера следующий оператор SQL => INSERT INTO comments (1, "Hello World").Где 1 - это что-то вроде идентификатора пользователя, а Hello World - что-то вроде комментария.Возможно, я бы не стал публиковать SQL-операторы для этого канала, но вместо этого JSON, который я могу легко использовать как из JavaScript (JSON.stringify / JSON.parse), так и из PHP (json_encode / json_decode).

Обновление

Вы не запускаете cron-job, потому что это побьет цель в пабе Redis.Например, я захожу на ваш сайт, который является блогом по адресу 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 вы извлекаете данные, которые я разместил, и вставляете их в MySQL, используя INSERT INTO comments (1, "Hello World").Когда происходит такая мутация, вам также нужно сообщить процессу 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.Эта часть важна!Процесс node.js всегда получает эти изменения благодаря pubsub в Redis.Каждый раз, когда скрипт php изменяет базу данных, вы должны публиковать эти изменения в Redis с publish.

PS: Надеюсь, это понятно.Может быть, позже, когда у меня будет немного времени, я обновлюсь, возможно, небольшим фрагментом ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...