Trying to create a socket between servers with SocketIO and PHPws - node.js

I'm having a bit of an issue with websockets. So, I have a Rpi that provides me some data through a socketIO client in a pretty simple way. The following code shows how do I get to get this data:
<!DOCTYPE html>
<html>
<header>
<title>SocketIO test</title>
<script src="http://192.168.5.5:8000/socket.io/socket.io.js"></script>
</header>
<body>
<script type="text/javascript">
var client = io.connect('http://192.168.5.5:8000');
client.on('connect', function() {
console.log('connected');
});
client.on('raw', function(data){
console.log(data);
});
client.on('state', function(data){
console.log(data);
});
</script>
</body>
However, what I need to implement is a little bit more complex. I need to use a Apache server to trait some of the data before it gets to the client side. The following image shows what I attempt to build:
To reach my goal I tried several WebSocket Servers and Client libraries for PHP until I found PHPws, which looks like the best solution for my scenario.
So, I read the examples, I test them and everything went well until I tried to connect to the Rpi with the following code:
require_once("../vendor/autoload.php");
$loop = \React\EventLoop\Factory::create();
$logger = new \Zend\Log\Logger();
$writer = new Zend\Log\Writer\Stream("php://output");
$logger->addWriter($writer);
$client = new \Devristo\Phpws\Client\WebSocket("ws://192.168.5.5:8000", $loop, $logger);
$client->on("connect", function() use ($logger, $client){
$logger->notice("Or we can use the connect event!");
$client->send("Hello world!");
});
$client->on("raw", function($message) use ($client, $logger){
$logger->notice("Got message: ".$message->getData());
$client->close();
});
$client->open()->then(function() use($logger, $client){
$logger->notice("We can use a promise to determine when the socket has been connected!");
});
$loop->run();
I've more or less taken this example from Devristo's github.
From the server side, the execution of the program is not throwing any error or message.
Is it possible to build what I want to build here with PHPws?
If so, am I connecting properly to de Rpi server with PHPws sample code shown?

It is possible :
[Node] Socket Server (This would be your RPi)
Simple socket.io server in node to check for a
(success) client connection event.
var io = require('socket.io')(1337);
io.on("connection",function(socket){console.log("[+] client",socket.id);})
[PHP] Socket Client
Using Elephant.IO we setup a client (Client Example for Socket.IO v2.0)
<?php
use ElephantIO\Client;
use ElephantIO\Engine\SocketIO\Version2X;
require __DIR__ . '/vendor/autoload.php';
$client = new Client(new Version2X('http://localhost:1337', [
'headers' => [
'X-My-Header: websocket rocks',
'Authorization: Bearer 12b3c4d5e6f7g8h9i'
]
]));
$client->initialize();
$client->emit('broadcast', ['foo' => 'bar']);
$client->close();
With this simple Client/Server example you will see the 'on connection' event in the node server when the browser opens the client.php

Related

Socket.io Multiple Connections on Client Side

I am trying to have a multiple socket io connections on the same page (client side). I have tried this answer but unfortunately it did not solved the problem, Link to SO question
Case:
I have a chat(bot) application running on localhost:3000
I have a CMS for the said chat(bot) application running on localhost:8000
My code currently:
1.Declare Script on index.html, (on localhost:3000)
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="js/main.js"></script>
2. Socket.io logic on main.js (on localhost:3000)
var socket = io('http://localhost:3000', {resource: '/socket.io', forceNew : true});
var cms_socket = io('http://localhost:8000', {resource: '/socket.io', forceNew : true});
socket.on('connect', console.log("SOCKET IO chat connected")) //WORKED
cms_socket.on('connect', console.log("SOCKET IO cms_connected")); //WORKED
socket.on('bot-reply', (data) => alert(data)) //WORKED
cms_socket.on('test_cms_socket', (data) => alert(data)) //NOT-WORKED
What confuses me is that the console log from both socket worked, telling both socket connects, though the cms_socket.on('test_cms_socket', ..) did not work.
Here is the logic from the CMS localhost:8000
function broadcast(req,res){
res.io.emit('test_cms_socket', "This is from CMS");
return res.redirect('/');
}
I have passed my socket.io to the middleware, used a tutorial from here
I do not really know if this helps or not, but I get this error from console. Any help would be very much appreciated
Uncaught TypeError: Cannot read property 'apply' of undefined
at r.emit (index.js:133)
at r.emit (socket.js:136)
at r.onconnect (socket.js:327)
at r.onpacket (socket.js:224)
at r.<anonymous> (index.js:21)
at r.emit (index.js:133)
at r.ondecoded (manager.js:345)
at s.<anonymous> (index.js:21)
at s.r.emit (index.js:133)
at s.add (index.js:241)

how to display a realtime variable in nodejs in HTML

I am using the setInterval() function to update a few variables(prices from various API's) every 'x' seconds in NodeJS
I want to display these variables in HTML and have them update real time every 'x' seconds.
How do I go about this using Socket.io or without using it
If you don't want to use socket.io, you can use AJAX calls but I think it's the more painful way...
If you use socket.io, there are great examples on their GitHub : Chat example.
In your NodeJS :
var io = require('socket.io')(8080); // The port should be different of your HTTP server.
io.on('connection', function (socket) { // Notify for a new connection and pass the socket as parameter.
console.log('new connection');
var incremental = 0;
setInterval(function () {
console.log('emit new value', incremental);
socket.emit('update-value', incremental); // Emit on the opened socket.
incremental++;
}, 1000);
});
This code should be start in your application.
And in your view :
<html>
<body>
<pre id="incremental"></pre>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var socket = io('http://localhost:8080'); // Connect the socket on the port defined before.
socket.on('update-value', function (value) { // When a 'update-value' event is received, execute the following code.
console.log('received new value', value);
$('#incremental').html(value);
});
</script>
</body>
</html>
My code isn't complete but shows the essential to know.
Try Templating and template engines.
Template engine are stuff that enable you to pass variables to Templates. These engines render the template file, with data you provide in form of HTML page.
I will suggest you to try 'ejs', as it very closely signify HTML files. ejs template are simply HTML syntax with placefolder for you to pass Data.
But that will require you to refresh the page continously after regular time. So you can try 'AJAX' which let you refresh part of page, simultaneously sends and receives data from server

socket.io node.js server "debug: destroying non-socket.io upgrade" message

I have a node.js socket server using socket.io.
I'm building a firefox addon, where I load a pageworker. The html in the following page is as follows:
<html>
<head>
<script type="text/javascript">
//THIS DOESN'T WORK
var exampleSocket = new WebSocket("ws://someip:port");
exampleSocket.onopen = function (event) {
console.log("socket opened!");
};
//THIS WORKS
var exampleSocketa = new WebSocket("ws://echo.websocket.org");
exampleSocketa.onopen = function (event) {
console.log("socket to echo opened!");
};
</script>
</head>
<body>
</body>
</html>
I can open a websocket to echo.websocket.org, but not my own server. I get a "debug: destroying non-socket.io upgrade" message. I can switch it off with the option: { 'destroy upgrade': false }, but then I see no debug output from server, and no connection is made.
What am I doing wrong? How can I get a socket open to my socket.io server?
So after some more googling, it turns out that I need to require socket.io on the client side. Even though socket.io uses websockets, it prefers talking to itself.

Node.js: Socket.io doesn't work

I've wrote a simple node.js app by socket.io some weeks ago. My program is fine on my PC but when i tried to run it on my laptop. I faced a really weird error on my console.
note that I'm running node on 127.0.0.1:2324. I don't know what is that ip (0.0.9.20) on the chrome console.
Again, my code is correct cause it's working fine on my PC.
And I get this on my cmd:
my paint.html code is something like this:
<script src="http://127.0.0.1/node/paint/js/jquery.js"></script>
<script src="http://127.0.0.1/node/paint/js/cursor.js"></script>
<script src="http://127.0.0.1/node/paint/js/controllers.js"></script>
<script src="http://127.0.0.1/node/paint/js/core.js"></script>
<script src="http://127.0.0.1:2324/socket.io/socket.io.js"></script>
<link href="http://127.0.0.1/node/paint/css/style.css" rel="stylesheet" />
core.js:
// broadcat function
function broadcast(data)
{
var socketio = io.connect(serverPort);
socketio.emit("message_to_server", { pen : data});
}
// receive data from server
var socketio = io.connect(serverPort);
socketio.on("message_to_client", function(data)
{
var res_brush = data['pen'];
var brush_data_rec = res_brush['pen'].split('|');
draw(brush_data_rec[0],
brush_data_rec[1],
brush_data_rec[2],
brush_data_rec[3],
brush_data_rec[4],
brush_data_rec[5],
brush_data_rec[6]);
});
update:
You should explicitly specify the target hostname on the client to connect to to avoid confusing the client on which address to connect to. There's also a cleaner way to specify a target port.
var socket = io.connect('http://localhost/', {
'port': 8080,
'transports': ['websockets']
});

Accessing server side functions using Express.js and EJS

I'm running a test app in Express.js using EJS as the templating engine. I'd like to access functions stored in a .js file to run server side and not client side. For instance if I have:
<%= console.log("I'm in the server console"); %>
the server catches the console output, and if I have:
<script type="text/javascript"> console.log("I'm in the client-side console"); </script>
Now if I have a function to output the same for the client side I can include it this way:
<script type="text/javascript" src="/javascripts/clientSideCode.js"> clientSideOutput(); </script>
But how do I include a file and its functions that way so EJS can execute server side code? It appears that the public folder in express is just for client side code.
You can create helper functions that your templates can access via app.locals:
http://expressjs.com/api.html#app.locals
You can use node.js and Socket.IO to emit real time events between client and server. For instance the client would do something like:
<script>window onload = function() {
socket.emit('request_customer_list', { state: "tx" });
socket.on('receive_customer_list', function(data) {
$.each(data.customer_list, function(key, value) {
socket.set(key, value); // store the customer data and then print it later
});
});}
On your server you can have a routine to load the customer list and send it back in similar format:
socket.on('connection')
socket.on('request_customer_list', function(data){
state = data.state;
var customer_list;
// pretend i loaded a list of customers from whatever source right here
socket.emit('receive_customer_list', {customer_list: customer_list});
)} )};

Resources