Skip to content

Instantly share code, notes, and snippets.

@gogl92
Last active March 31, 2018 09:26
Show Gist options
  • Save gogl92/7ecf62d4f5b7ea7edf04a031c4b0a137 to your computer and use it in GitHub Desktop.
Save gogl92/7ecf62d4f5b7ea7edf04a031c4b0a137 to your computer and use it in GitHub Desktop.
Yii2 + redis + node + vue / JQuery
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace app\assets;
use yii\web\AssetBundle;
/**
* Main application asset bundle.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
'https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js'
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
# Install Redis
wget http://download.redis.io/releases/redis-4.0.9.tar.gz
tar xzf redis-4.0.9.tar.gz
cd redis-4.0.9
make
# Install yii2 redis extension
composer require --prefer-dist yiisoft/yii2-redis
# Install vue
composer require --prefer-dist aki/yii2-vue
# Install Node libs
npm install express
npm install socket.io
npm install redis
# run redis server
src/redis-server
# Open redis cli monitor
src/redis-cli monitor
#run the node script
node server.js
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
$this->title = 'My Yii Application';
\aki\vue\Vue::begin([
'jsName' => 'app',
'id' => "chat",
'data' => [
'id' => "init code",
'url' => 'http://localhost:8890',
'notifications' => [],
'name_field' => '',
'message_field' => ''
],
'methods' => [
'send_post' => new yii\web\JsExpression("function(){
$.post( '?r=site/message',{name: this.name_field,
message: this.message_field}).done(function( data ) {
$('#message-field').val('');
});
return false;
}"),
],
'mounted' => new yii\web\JsExpression("function (){
}")
]);
$js = <<<JS
var socket = io.connect(app.url);
socket.on('notification', function (data) {
var message = JSON.parse(data);
console.log(message);
app.notifications.push({'name':message.name,'message':message.message});
});
$("#message-field").val("");
JS;
$this->registerJs($js, \yii\web\View::POS_READY);
?>
<div class="site-index">
<div class="body-content">
<div class="row">
<div class="well col-lg-8 col-lg-offset-2">
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<?= Html::textInput('name', null, [
'class' => 'form-control',
'placeholder' => 'Name',
'v-model' => 'name_field'
]) ?>
</div>
</div>
<div class="col-xs-7">
<div class="form-group">
<?= Html::textInput('message', null, [
'id' => 'message-field',
'v-model' => 'message_field',
'class' => 'form-control',
'placeholder' => 'Message',
]) ?>
</div>
</div>
<div class="col-xs-2">
<div class="form-group">
<?= Html::a('Send', null, [
'class' => 'btn btn-block btn-success',
'@click' => 'send_post'
]) ?>
</div>
</div>
</div>
<div id="notifications">
<template v-for="notification in notifications">
<p><strong>{{notification.name}}</strong>: {{notification.message}}</p>
</template>
</div>
</div>
</div>
</div>
</div>
<?php \aki\vue\Vue::end(); ?>
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(8890);
io.on('connection', function (socket) {
console.log("new client connected");
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.on("message", function(channel, message) {
console.log("New message: " + message + ". In channel: " + channel);
socket.emit(channel, message);
});
socket.on('disconnect', function() {
redisClient.quit();
});
});
<?php
namespace app\controllers;
use app\models\ContactForm;
use app\models\LoginForm;
use Yii;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\helpers\Json;
use yii\web\Controller;
use yii\web\Response;
class SiteController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
'message' => ['post'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
/**
* Displays homepage.
*
* @return string
*/
public function actionIndex()
{
return $this->render('index');
}
public function actionMessage()
{
file_put_contents('result',Json::encode(Yii::$app->request->post()));
if (Yii::$app->request->post()) {
$name = Yii::$app->request->post('name');
$message = Yii::$app->request->post('message');
return Yii::$app->redis->executeCommand('PUBLISH', [
'channel' => 'notification',
'message' => Json::encode(['name' => $name, 'message' => $message])
]);
}
return false;
}
/**
* Login action.
*
* @return Response|string
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
$model->password = '';
return $this->render('login', [
'model' => $model,
]);
}
/**
* Logout action.
*
* @return Response
*/
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
/**
* Displays contact page.
*
* @return Response|string
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
}
return $this->render('contact', [
'model' => $model,
]);
}
/**
* Displays about page.
*
* @return string
*/
public function actionAbout()
{
return $this->render('about');
}
}
<?php
$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
],
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'redis' => [
'class' => 'yii\redis\Connection',
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
],
'db' => $db,
/*
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
*/
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment