How to emit a socket.io event from a PHP controller? - php

I'm developping a PHP website using the Yii2 Framework and I'm trying to implement a socket.io service.
To execute socket.io I use PM2 and my file looks like this :
const { fstat } = require('fs');
var socket = require('socket.io'),
express = require('express'),
https = require('https');
fs = require('fs');
const credentials = {
key: fs.readFileSync('../../../ssl/keys/<path_to_cert_key.key>').toString(),
cert: fs.readFileSync('../../../ssl/certs/<path_to_cert.crt>').toString(),
}
var app = express();
var server = https.createServer(credentials, app);
var io = socket(server, {
cors: {
origin: '<origin_url>',
methods: ['POST', 'GET'],
credentials: true
},
allowEIO3: true,
secure: true
});
io.sockets.on('connection', function(client){
console.log('ok');
client.on('test', function(data){
console.log('test');
console.log(data);
io.sockets.emit('test_r', {message: 'ok'});
});
});
server.listen(30064);
It runs without any error:
pm2 start _socket.js
I can easily access this socket from a view by registering javascript :
var socket = io.connect('<socket_url:port>', {
withCredentials: false,
});
socket.on('test_r', function( data ) {
console.log('it works');
});
It works well if I connect to the socket and emit from a view.
But the thing is that I want to emit an event from a PHP Controller or from a CoreBootstrap Object in a php function like this :
$emitter = new \SocketIO\Emitter( array( 'port' => '30064', 'host' => '127.0.0.1') );
$emitter->broadcast->emit( 'test', ['message' => 'test_message'] );
The module I'm using is ashiina/socket.io-emitter (I also tried a bunch of ohters but they did not work as well).
Nothing happens when I do this. Nothing even happens when I look at the PM2 logs.
Would someone know why the event is not emitted or if there is another way to do it ?
Thanks in advance for your answers.

Related

Problem with multiple Axios GET Requests NodeJS/MySQL Events

i have a problem with my NodeJS/MySQL-Events (from rodrigogs on Github) solution and hope someone here can help me.
Current setup looks like this:
MySQL Server <-> Socket.io with MySQL-Events listening for new Database Entrys (trigger on INSERT and UPDATE)
-> Axios GET Request from index.js to sync.php (different Server)
-> calling Method from class.php inside sync.php with data from that GET Request
No problems with Socket.IO clients. Just with to many GET Request at the same time from NodeJS/Socket Server -> Apache
If i get just a few new database entrys separately, everything works fine.
If i get a lot of new database entrys at almost the same time, some of them not running the Method from sync.php/class.php
index.js (Node/Socket Server with MySQL-Events Trigger)
const program = async () => {
const instance = new MySQLEvents(conn, {
startAtEnd: true,
excludedSchemas: {
mysql: true,
},
});
await instance.start();
const agent = new https.Agent({
rejectUnauthorized: false
});
instance.addTrigger({
name: 'INSERT',
expression: 'table.column',
statement: MySQLEvents.STATEMENTS.INSERT,
onEvent: (event) => {
console.log("New Entry in Database " + event)
const id = event.affectedRows[0].after.ID;
const status = event.affectedRows[0].after.STATUS;
if (status === 11) {
axios.get('https://serverurl.dev/sync.php', {
params: {
id: id,
status: status
},
withCredentials: true,
httpsAgent: agent,
auth: {
username: 'user',
password: 'pwd'
}
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
}
});
instance.on(MySQLEvents.EVENTS.CONNECTION_ERROR, console.error);
instance.on(MySQLEvents.EVENTS.ZONGJI_ERROR, console.error);
};
serverurl.dev/sync.php
<?php
if (!empty($_GET)){
$id = $_GET['id'];
$status = $_GET['status'];
$classname->method($id, $status);
}
serverurl.dev/class.php
public function method($id, $status)
{
// lots of things happen here
}
My guess is that the method in class.php isnt finished running while the next GET Requests are coming in and calling the method again to fast?
Any ideas how to solve this problem?

Socket.io Error on server

I am tried to use socket io on the live server and I got this error.
polling-xhr.js:264 GET http://sub.domain.com:3000/socket.io/?EIO=3&transport=polling&t=MFUVMS5 net::ERR_TIMED_OUT
But on my local server, the files worked perfectly. I am working with socket.io and PHP.
Here are my codes:
server.js
var socket = require('./node_modules/socket.io');
var express = require('./node_modules/express');
var app = express();
var server = require('http').createServer(app);
var io = socket.listen(server);
var port = process.env.PORT || 3000;
// server active console view
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
io.on('connection', function (socket) {
// show new added online user
socket.on('now_online', function (data) {
io.sockets.emit('now_online',{
id: data.id,
name: data.name
});
});
});
main.js
var socket = io.connect('http://'+window.location.hostname+':3000');
socket.on('new_online_user', function (data) {
if (login_id != data.online_user) {
$('#contacts-list .contact[data-chat='+data.online_user+']'+' .contact-status').addClass('online');
}
});
package.json
{
"private": true,
"dependencies": {
"gulp": "^3.9.1",
"express": "^4.16.2",
"socket.io": "^2.0.4"
}
}
I was searching in google and StackOverflow about this issue but those solved didn't work for me.
Thanks so much.
Try connecting using only domain without http like:
var socket = io.connect(window.location.hostname+':3000', {transports: ["websocket", "xhr-polling", "htmlfile", "jsonp-polling"]});
It will automatically become ws://sub.domain.com:3000/socket.io/?EIO=3&transport=polling&t=MFUVMS5. I'm using similar to this and working fine.

How to use browser sync external url with PHP in android?

I've tried to open my joomla site in the Android browser with browserSync external URL.
I use wamp to run the server on pc.Is there a way to set up PHP and a web server on an Android device ?
How can I run joomla or php site on my Android device with browserSync ?
Terminal
external url in browser
my gulpfile.js:
var gulp = require('gulp'),
watch = require('gulp-watch'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssVars = require('postcss-advanced-variables'),
cssImport = require('postcss-import'),
nested = require('postcss-nested'),
browserSync = require('browser-sync').create();
gulp.task('styles', function() {
var processors = [
cssImport,
cssVars,
nested,
autoprefixer({
browsers: ['last 2 versions']
})
];
return gulp.src('./assets/styles/styles.css')
.pipe(postcss(processors))
.pipe(gulp.dest('./temp/styles'));
});
gulp.task('watch', function() {
browserSync.init({
proxy: "localhost/j2shop",
port: 8080,
notify: false,
watchTask: true,
debugInfo: true,
logConnections: true
});
watch('./assets/includes/**/*.php', function() {
browserSync.reload();
});
watch('./assets/styles/**/*.css', function() {
gulp.start('cssInject');
});
});
gulp.task('cssInject', ['styles'], function() {
return gulp.src('./temp/styles/styles.css')
.pipe(browserSync.stream());
});
Just run gulp. That will start Browsersync running and it will report to you in Terminal what the external url to enter on your device is. It will be something like http://10.0.1.12:3000. Just enter that on your Android and you will see your site.

REST server responds with javascript browser error (HTML) instead of json

I'm using Node.js (on AWS Lambda for alexa skill) to request my web server for a JSON file. But my server responds with a 'Javascript' not supported error html.
This is my code:
function httpsGet(myData, callback) {
// Update these options with the details of the web service you would like to call
var options = {
host: 'alexa0788.byethost24.com',
port: 80,
path: '/sample.php',
method: 'GET',
};
var req = http.request(options, res => {
res.setEncoding('utf8');
var returnData = "";
res.on('data', chunk => {
returnData = returnData + chunk;
});
res.on('end', () => {
console.log(returnData);
var pop = JSON.parse(returnData).firstName + JSON.parse(returnData).lastName;
callback(pop); // this will execute whatever function the caller defined, with one argument
});
});
req.end();
}
How can I make my server respond with the intended json and not force the client to support javascript? At the moment, I'm having a php file output the json. I tried calling a .json file too directly, instead of making a php file output json, but I see the same error.

Changing node.js server to Apache server

I was working with react-webpackage and running the project into node.js
Now due to demand , i have to add some php files in the project but i don't know how to add php file in my project and now transfer my project from node.js to Xampp and run my project with xampp... can you please guide me with that.
I am using this webpack "https://github.com/srn/react-webpack-boilerplate".
And my webpack index.js file looks like this.
'use strict';
var fs = require('fs');
var path = require('path');
var express = require('express');
var app = express();
var compress = require('compression');
var layouts = require('express-ejs-layouts');
app.set('layout');
app.set('view engine', 'ejs');
app.set('view options', {layout: 'layout'});
app.set('views', path.join(process.cwd(), '/server/views'));
app.use(compress());
app.use(layouts);
app.use('/client', express.static(path.join(process.cwd(), '/client')));
app.disable('x-powered-by');
var env = {
production: process.env.NODE_ENV === 'production'
};
if (env.production) {
Object.assign(env, {
assets: JSON.parse(fs.readFileSync(path.join(process.cwd(), 'assets.json')))
});
}
app.get('/*', function(req, res) {
res.render('layout', {
env: env
});
});
var port = Number(process.env.PORT || 3001);
app.listen(port, function () {
console.log('server running at localhost:3001, go refresh and see magic');
});
if (env.production === false) {
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var webpackDevConfig = require('./webpack.config.development');
new WebpackDevServer(webpack(webpackDevConfig), {
publicPath: '/client/',
contentBase: './client/',
inline: true,
hot: true,
stats: false,
historyApiFallback: true,
headers: {
'Access-Control-Allow-Origin': 'http://localhost:3001',
'Access-Control-Allow-Headers': 'X-Requested-With'
}
}).listen(3000, 'localhost', function (err) {
if (err) {
console.log(err);
}
console.log('webpack dev server listening on localhost:3000');
});
}
basically i want to declare some variables in php and fetch them to javascript.so just want to add one file in webpack(file named as index.php) and then all my project work normally
Thanks.
You can't run express on the same port of xampp, you have to use different ports (or different servers) to serve the php file.

Categories