yii-node-socket Connect php, javascript, nodejs in one Yii application.

  1. Requirements
  2. Installation
  3. Console command actions
  4. Javascript
  5. PHP
  6. TODO
  7. Resources

If you need create more live application this extension helps you with it.

Based on nodejs socket.io library.

Features:

  • yii2 supported from 2.0.1 release see on github
  • emit events to all connected clients
  • create rooms and emit events into some room
  • set up data in nodejs memory from php and get in from javascript
  • invoke any function or method of object in javascript (in window scope) from php
  • browser support

Github page

Requirements

OS: linux/unix/windows
git installed

Installation

Install nodejs, if not installed see nodejs official site
Install extension

  • Using git clone
    $> git clone https://github.com/oncesk/yii-node-socket.git
    

Now go to the folder where you install extension application.ext.yii-node-socket and execute

$> git submodule init
$> git submodule update

Yii configuration

  • Configure console command in (main/console.php). You can use config below:
'commandMap' => array(
    'node-socket' => 'application.extensions.yii-node-socket.lib.php.NodeSocketCommand'
)
  • Register Yii component, need to add into main.php and console.php:
'nodeSocket' => array(
    'class' => 'application.extensions.yii-node-socket.lib.php.NodeSocket',
    'host' => 'localhost',  // default is 127.0.0.1, can be ip or domain name, without http
    'port' => 3001      // default is 3001, should be integer
)

Install nodejs components in application.ext.yii-node-socket.lib.js.server:

$> npm install

Congratulation, installation completed!

Notice: if the name of the component will not be nodeSocket, your need to use special key in console command --componentName=component_name

Console command actions

$> ./yiic node-socket # show help
$> ./yiic node-socket start # start server
$> ./yiic node-socket stop # stop server
$> ./yiic node-socket restart # restart server
$> ./yiic node-socket getPid # show pid of nodejs process

Javascript

before work in javascript you need start server (./yiic node-socket start) and register clients scripts in PHP (see below, into PHP section)

// create object and connect to web socket server
var socket = new YiiNodeSocket();

// enable debug mode
socket.debug(true);

// add event listener
socket.on('updateBoard', function (data) {
    // do any action
});

socket.room('testRoom').join(function (success, numberOfRoomSubscribers) {
    // success - boolean, numberOfRoomSubscribers - number of room members
    // if error occurred then success = false, and numberOfRoomSubscribers - contains error message
    if (success) {
        console.log(numberOfRoomSubscribers + ' clients in room: ' + roomId);
        // do something

        // bind events
        this.on('join', function (newMembersCount) {
            // fire on client join
        });

        this.on('data', function (data) {
            // fire when server send frame into this room with 'data' event
        });
    } else {
        // numberOfRoomSubscribers - error message
        alert(numberOfRoomSubscribers);
    }
});

PHP

Registering client scripts

Yii::app()->nodeSocket->registerClientScripts();
Frames

Frame - data package for nodejs server wrapped into Class. Per one request to nodejs server you can send only 1 frame. For send several frames at a time use Multiple frame.

Frames:

  • Event - send event to javascript
  • Invoke - invoke javascript function or method of object in window scope
  • PublicData - set up shared data into nodejs memory, any client can get it
  • Multiple - needed for sending more several frames per a time
Event frame
// create event frame
$frame = Yii::app()->nodeSocket->createEventFrame();

// set event name
$frame->setEventName('updateBoard');

// set data using ArrayAccess interface
$frame['boardId'] = 25;
$frame['boardData'] = $html;

// or you can use setData(array $data) method
// setData overwrite data setted before

$frame->send();
Set up shared data

Notice: You can set expiration using setLifeTime(integer $lifetime) method of class PublicData

// create frame
$frame = Yii::app()->nodeSocket->createPublicDataFrame();

// set key in storage
$frame->setKey('error.strings');

// set data
$frame->setData($errorStrings);

// you can set data via ArrayAccess interface
// $frame['empty_name'] = 'Please enter name';

// set data lifetime
$frame->setLifeTime(3600*2);    // after two hours data will be deleted from storage

// send
$frame->send();
Send event into room
// create frame
$frame = Yii::app()->nodeSocket->createEventFrame();

// set event name
$frame->setEventName('updateBoard');

// set room name
$frame->setRoom('testRoom');

// set data
$frame['key'] = $value;

// send
$frame->send();
Invoke javascript function
$invokeFrame = Yii::app()->nodeSocket->createInvokeFrame();
$invokeFrame->invokeFunction('alert', array('Hello world'));
$invokeFrame->send();   // alert will be showed on all clients
DOM manipulations with jquery

Task: you need update price on client side after price update in each product

...

$product = Product::model()->findByPk($productId);
if ($product) {
    $product->price = $newPrice;
    if ($product->save()) {
        $jFrame = Yii::app()->nodeSocket->createJQueryFrame();
        $jFrame
            ->createQuery('#product' . $product->id)
            ->find('span.price')
            ->text($product->price);
        $jFrame->send();
        // and all connected clients will can see updated price
    }
}

...

Send more than one frame per a time

Example 1:

$multipleFrame = Yii::app()->nodeSocket->createMultipleFrame();

$eventFrame = Yii::app()->nodeSocket->createEventFrame();

$eventFrame->setEventName('updateBoard');
$eventFrame['boardId'] = 25;
$eventFrame['boardData'] = $html;

$dataEvent = Yii::app()->nodeSocket->createPublicDataFrame();

$dataEvent->setKey('error.strings');
$dataEvent['key'] = $value;

$multipleFrame->addFrame($eventFrame);
$multipleFrame->addFrame($dataEvent);
$multipleFrame->send();

Example 2:

$multipleFrame = Yii::app()->nodeSocket->createMultipleFrame();

$eventFrame = $multipleFrame->createEventFrame();

$eventFrame->setEventName('updateBoard');
$eventFrame['boardId'] = 25;
$eventFrame['boardData'] = $html;

$dataEvent = $multipleFrame->createPublicDataFrame();

$dataEvent->setKey('error.strings');
$dataEvent['key'] = $value;

$multipleFrame->send();

See github for more documentation above!

TODO

  • implement https (this is done but not commited, only for yii1 yet)

Resources

4 0
20 followers
0 downloads
Yii Version: 1.1
License: BSD-2-Clause
Category: Networking
Developed by: once
Created on: Nov 13, 2013
Last updated: 9 years ago

Related Extensions