Socket.io 1.0 emitting events from php

Continue to play with socket.io. Last time I used 0.8 version. Right now socket.io has 1.0 with a lot of updates. So let’s get started.

The most cool thing IMO is adapter

var io = require('socket.io')(serverForUI),
io.adapter(redis({ host: 'localhost', port: 6379 }));

I’m brand new guy in node world. So for me explanation in docs was a little bit confusing. But this 2 lines of code add a lot of magic. Right now you can publish events to redis (in specific format) and after that those events will automatically go to client.
In order to emit some data from php. I used socket.io-php-emitter. So all we need to do is:

// node server
var serverForUI = require('http').createServer(),
    redisAdapter = require('socket.io-redis'),
    io = require('socket.io')(serverForUI);

io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));

serverForUI.listen(8000);

// emit events from php side

<?php

namespace myapp;

use SocketIO\emitter;

class OrganizationUpdates
{

    public $host;
    public $port = 6379;

    private $_emitter;

    /**
     * Return redis queue
     * @return emitter
     */
    private function _emitter()
    {
        if (!$this->_emitter) {
            $redis = new \Redis();
            $redis->connect($this->host, $this->port);

            $this->_emitter = new emitter($redis);
        }
        return $this->_emitter;
    }

    public function publishNewEvent($eventType, $data)
    {
        $this->_emitter()->emit("news", [
            'event_type' => $eventType,
            'data' => $data
        ]);
    }
}

The last thing is our client example

<!doctype html>
<html>
<head>
    <title>Test</title>
</head>
<body>
<script src="https://cdn.socket.io/socket.io-1.0.6.js"></script>
<script>
    var socket = io('http://localhost:8000', {
        transports: ['websocket']
    });

    socket.on('news', function (data) {
        console.log(data);
    });
</script>
</body>
</html>

That’s it. Next time I’ll tell you about socket.io authorization and using rooms.

12 thoughts on “Socket.io 1.0 emitting events from php

  1. Beck

    Hi, please help me with my script

    Your script generates an error

    /var/www/test.js:10
    var socket = io(‘http://localhost:8000’, {
    ^
    TypeError: object is not a function
    at Object. (/var/www/test.js:10:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

    I`m use socket.io 1.0.6.
    I understand the case in version socket.io, rewrote the script like this:

    var serverForUI = require(‘http’).createServer(),
    redisAdapter = require(‘socket.io-redis’),
    io = require(‘socket.io’)(serverForUI);

    io.adapter(redisAdapter({ host: ‘127.0.0.1’, port: 6379 }));

    serverForUI.listen(8000);

    io.set(“transports”, [“websocket”]);
    io.sockets.on(‘connection’, function (socket) {
    console.log(‘connected’);
    socket.on(‘news’, function (data) {
    console.log(data);
    });
    });

    And it does not work.

    What’s the problem?

    Reply
  2. Beck

    I created a test scipt


    var serverForUI = require('http').createServer(),
    redisAdapter = require('socket.io-redis'),
    io = require('socket.io')(serverForUI);

    io.adapter(redisAdapter({ host: '127.0.0.1', port: 6379 }));
    var redis = require('redis');
    serverForUI.listen(8000);

    var client = require("redis").createClient(),
    util = require("util");

    client.monitor(function (err, res) {
    console.log("Entering monitoring mode.");
    });
    client.on("monitor", function (time, args) {
    console.log(time + ": " + util.inspect(args));
    });
    client.on("message", function (time, args) {
    console.log(time + ": " + util.inspect(args));
    });

    io.on('connection', function (socket) {
    console.log('connected');
    socket.on('news', function (data) {
    console.log('news event');
    });
    });

    After send emit in php, i can see in console only:

    Entering monitoring mode.
    1404827050.872076: [ 'PUBLISH',
    'socket.io#emitter',
    '\\x92\\x83\\xa4type\\x02\\xa4data\\x92\\xa4news\\x82\\xa8property\\xaamuch value\\xa7another\\xabvery object\\xa3nsp\\xa1/\\x82\\xa5rooms\\x90\\xa5flags\\x90' ]

    Reply
  3. admin Post author

    > Do you speak russian?
    Yes I do) You can ping me via my email, you’ll find it here http://radzserg.com/cv/

    After send emit in php, i can see in console only:

    Entering monitoring mode.
    1404827050.872076: [ ‘PUBLISH’,
    ‘socket.io#emitter’,
    ‘\\x92\\x83\\xa4type\\x02\\xa4data\\x92\\xa4news\\x82\\xa8property\\xaamuch value\\xa7another\\xabvery object\\xa3nsp\\xa1/\\x82\\xa5rooms\\x90\\xa5flags\\x90’ ]

    Yeah that’s great.

    But you don’t need
    var redis = require(‘redis’);
    var client = require(“redis”).createClient(),

    In fact io.adapter(redisAdapter({ host: ‘127.0.0.1’, port: 6379 })); will do all the job for you. It will subscribe to redis events and will automatically send it to your client

    Reply
  4. Beck

    Еще раз привет.

    Возник вопрос. Как можно из nodejs отправить данные в php определенному скрипту. Просто не хочется отправлять от клиента ajax, хочу по сокету данные отправить.

    Reply
  5. admin Post author

    В любом случае придется делать в 2 этапа сначала кидать их по сокету
    http://socket.io/docs/
    socket.emit(‘my other event’, { my: ‘data’ });

    А тут мне видится 2 пути
    1. Теоретически нода таким же образом запихнет это в редис . То про что ты писал.
    1404827050.872076: [ ‘PUBLISH’,
    ‘socket.io#emitter’,
    ‘\\x92\\x83\\xa4type\\x02\\xa4data\\x92\\xa4news\\x82\\xa8property\\xaamuch value\\xa7another\\xabvery object\\xa3nsp\\xa1/\\x82\\xa5rooms\\x90\\xa5flags\\x90’ ]

    Только теперь надо делать наоборот. Со стороны php подписываться на socket.io#emitter парсить и обрабатывать.

    2. На стороне ноды обрабатывать.
    socket.on(‘news’, function (data) {
    и уже тут пихать или в редис в какую-то свою очередь или в бд или еще как-то
    });

    Мне кажется второй вариант по-проще. Для меня самого все это достаточно ново)

    Reply
  6. Timofey

    А как присоединить сокет в новую комнату? Задача такая, пользователь нажимает ссылку на сайте чтобы перейти в другую комнату, его запрос обрабатывает php-скрипт, делает всякие проверки и записи в бд, а затем через socket.io-php-emitter выбрасывает событие о присоединении нового участника на клиент. Ок, но как самого пользователя(сокет) присоединить в эту комнату?

    Переход в другую комнату делается ajax-запросом, то есть страница не перегружается полностью и нужно в рамках этого сокета присоединить его к новой комнате и отсоединить от старой.

    Reply
  7. Timofey

    Думаю таких проблем бы не возникло, если можно было бы выбрасывать события из php не только на клиентскую, но и на сервеную часть socket.io

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *