emit() not working [Node.js] - javascript

I subscibe to laravel 5 event[channal] update.group and I recive message in console after I trigger event but on client side in browser I don't recive any message. Also after I trigger event I recive message in console and then node server stop working with message:
bash-4.2# node node.js
Listening on Port 3000
Message Recieved: testasdsa
/home/client/public_html/node_modules/ioredis/lib/parsers/javascript.js:216
throw err;
^
SyntaxError: Unexpected token e
at Object.parse (native)
at Redis.<anonymous> (/home/client/public_html/node_modules/node.js:10:20)
at Redis.emit (events.js:110:17)
at Redis.exports.returnReply (/home/client/public_html/node_modules/ioredis/lib/redis/parser.js:79:16)
at ReplyParser.<anonymous> (/home/client/public_html/node_modules/ioredis/lib/redis/parser.js:27:10)
at ReplyParser.emit (events.js:107:17)
at ReplyParser.send_reply (/home/client/public_html/node_modules/ioredis/lib/parsers/javascript.js:281:8)
at ReplyParser.execute (/home/client/public_html/node_modules/ioredis/lib/parsers/javascript.js:210:14)
at Socket.<anonymous> (/home/client/public_html/node_modules/ioredis/lib/redis/event_handler.js:90:22)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:538:20)
Here is my node.js file:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('update.group', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.sockets.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
And for client side:
var socket = io.connect('127.0.0.1:3000');
socket.on("update.group", function(message){
// increase the power everytime we load test route
console.log(message);
});
Anyone can find what is problem?

It's pretty obvious from your debug output: testasdsa is not valid JSON, so you cannot parse it as such. You will need to change the code that publishes the messages so that it's properly JSON encoded.
Since it looks like you're expecting event and data properties on an object, the publisher would need to be writing something like { "event": "foo", "data": "testasdsa" }.
To fix the problem of browser clients not getting the events, you need to change this in your server script:
io.sockets.emit(channel + ':' + message.event, message.data);
to:
io.sockets.emit(message.event, message.data);
Then just make sure the publisher sends out something like { "event": "update.group", "data": "somedata" }

Related

Javascript client will not connect to node.js server through websocket

I am trying to connect a client, ran in a web browser, to a server using websockets.
My client is written in javascript and my server is node.js. I have managed to connect a node.js client with my server but cannot seem to connect my javascript client to the server.
server code:
var webSocketServer = require("websocket").server;
var http = require("http");
var port = 9000;
var server = http.createServer(function (request, response) {
console.log(new Date() + " Received request");
});
server.listen(port, function () {
console.log(new Date() + " listening on port 9000");
});
var socket = new webSocketServer({
httpServer: server
});
socket.on("request", function (request) {
var connection = request.accept(null, request.origin);
connection.on("message", function (message) {
console.log(message.utf8Data);
});
});
client code:
var client = new WebSocket("ws://localhost:9000");
client.onopen = function () {
client.send("Handshake from client");
}
I expected to see the handshake from client output in my command prompt from which I ran my server. This does not happen. In my browsers console I eventually get this error:
WebSocket connection to 'ws://localhost:9000/' failed: WebSocket opening handshake timed out
I tried to console.log my client object and the output was this:
WebSocket {url: "ws://localhost:9000/", readyState: 0, bufferedAmount: 0, onopen: null, onerror: null, …}
So as far as I know the object is being built correctly and pointing at the correct URL but still fails to make the connection.

Node.js UDP Multicast over Network

I'm having an issue with a repeated EADDRNOTAVAIL issue on a UDP multicast proof of concept. I have a Linux server sending multicast messages to a Windows client (have tried reversing this to no avail..). The server works correctly when running both the client and the server on the same machine, but not over the same network.
Below is the code I've tried to get this to work with, the IPs I'm using, and the errors I've received.
I'm not sure what I'm doing incorrectly!
Environment
Windows Local IP: 192.168.1.10
Linux Local IP: 192.168.1.11
Server: server.js
const SRC_PORT = 6025;
const PORT = 6024;
const MULTICAST_ADDR = '239.255.255.250';
const LOCAL_IP = '192.168.1.11';
const dgram = require('dgram');
const server = dgram.createSocket("udp4");
server.bind(SRC_PORT, LOCAL_IP, function () {
setInterval(function () {
let message = new Buffer(new Date().toLocaleTimeString());
server.send(message, 0, message.length, PORT, MULTICAST_ADDR, function () {
console.log("Sent '" + message + "'");
});
}, 4000);
});
Client: client.js
const PORT = 6024;
const MULTICAST_ADDR = '239.255.255.250';
const LOCAL_IP = '192.168.1.10';
const HOST_IP = '192.168.1.11';
const dgram = require('dgram');
const client = dgram.createSocket('udp4');
client.on('listening', function () {
let address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, rinfo) {
console.log('Message from: ' + rinfo.address + ':' + rinfo.port + ' - ' + message);
});
//*** Also tried with client.bind(PORT, LOCAL_IP, ... and failed
client.bind(PORT, function () {
client.addMembership(MULTICAST_ADDR, HOST_IP);
});
Error
dgram.js:508
throw errnoException(err, 'addMembership');
^
Error: addMembership EADDRNOTAVAIL
at exports._errnoException (util.js:1026:11)
at Socket.addMembership (dgram.js:508:11)
at Socket.<anonymous> (~/dev/node-multicast/client.js:16:10)
at Socket.g (events.js:286:16)
at emitNone (events.js:91:20)
at Socket.emit (events.js:185:7)
at startListening (dgram.js:121:10)
at dgram.js:228:7
at _combinedTickCallback (internal/process/next_tick.js:77:11)
I'm sure you joined wrong multicastInterface from this error:
addMembership EADDRNOTAVAIL
It should be your address of local interface:
client.addMembership(MULTICAST_ADDR, LOCAL_IP);
As the doc says:
socket.addMembership(multicastAddress[, multicastInterface])
Tells the kernel to join a multicast group at the given
multicastAddress and multicastInterface using the IP_ADD_MEMBERSHIP
socket option. If the multicastInterface argument is not specified,
the operating system will choose one interface and will add membership
to it. To add membership to every available interface, call
addMembership multiple times, once per interface.

why websocket connection creation does not pass through http?

i tumbled across websocket and http.
I have written below example:
var fs = require('fs');
var server = http.createServer(function(request, response) {
console.log ("HTTP Request created...");
// I am responding something here..
});
server.listen(1234, function() {
console.log((new Date()) + ' Server is listening on port 1234');
});
var WebSocketServer = require('websocket').server;
wsServer = new WebSocketServer({
httpServer: server
});
wsServer.on('request', function(re){
var conn = re.accept(null, re.origin);
console.log ("Accepted New Connection..");
conn.on('message', function(message) {
console.log ('message received' + message.utf8Data);
});
});
I tried in two ways connecting to this server.
1) Through Browser.
2) through node.js application
When I tried reaching this server through browser ex: http:IP:1234,
I get "HTTP Request received.." gets printed, where as when I try with
below code in Node.js, I do not see this message getting printed.
var WebSocket = require('ws')
ws = new WebSocket('ws://IP:1234');
ws.on('open', function() {
console.log ("WebSocket opened..");
ws.send('something');
});
ws.on('message', function(message) {
console.log('received: %s', message.data);
});
When I tried to connect to webserver through
ws = new WebSocket('ws://IP:1234');
why is It not getting through HTTP?. My basic understanding is Websocket is just an upgrade on top of HTTP, in that case, I would assume WebSocket(), in turn connectes through HTTP to the server right?. Or Am i confused?.
Websocket requests don't trigger a request event on the HTTP server instance (for which the function you pass to createServer is a listener).
If you want to watch websocket requests on the HTTP server, listen to upgrade events:
server.on('upgrade', function (req, socket, head) { ... });
I assume it's because http will handle the handshake/upgrade itself that this is done through a different event.

Porting this PHP RS232 code to Node.js

I'm trying to port this simple PHP script to node.js.
The TV uses RS232 and the command is PON for on; POF for off.
This example successfully turns my TV On:
<?php
$rs232_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($rs232_sock, '10.0.1.155', '4999');
$rs232_in = pack("H*" ,'02'.bin2hex('PON').'03');
socket_write($rs232_sock, $rs232_in, strlen($rs232_in));
?>
I have this started for NodeJS:
var net = require('net');
var jspack = require('jspack/jspack.js').jspack;
client.connect('4999','10.0.1.155', function(){
console.log('CONNECTED');
// Send the RS232 command
client.write(jspack.Pack("H",'02'+bin2hex(command)+'03'));
}).on('data', function(data) {
// log the response
console.log('DATA: ' + data);
// Close the connection
client.destroy();
});
This is causing:
net.js:618
throw new TypeError('invalid data');
^
TypeError: invalid data
at Socket.write (net.js:618:11)
at Socket.<anonymous> (/Users/paul/Sites/homebridge-globalcache-gc100/test.js:79:10)
at Socket.g (events.js:261:16)
at emitNone (events.js:73:20)
at Socket.emit (events.js:167:7)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1051:10)
You don't need extra libraries to send binary data. Something like this should be sufficient:
var net = require('net');
var PON_MSG = new Buffer('\x02PON\x03', 'binary');
var POF_MSG = new Buffer('\x02POF\x03', 'binary');
client.connect('4999','10.0.1.155', function() {
console.log('CONNECTED');
// Replace `PON_MSG` with `POF_MSG` to do POF instead
client.write(PON_MSG);
}).on('data', function(data) {
console.log('DATA: %j', data);
});
Also be aware that the data event can fire multiple times, so when you can safely end the connection (if the remote side doesn't do so automatically) depends on the protocol (to make sure you have received the entire response).

Nodejs ssh2 run multiple command only one terminal

I am in a trouble while coding ssh2 module in my project. I tried to run multiple commands on one terminal for ruling remote Linux system. For example "bc" command provides you a basic calculator and you can run it for basic operations. but that kind of processes need to be awake when you are using (it will accepts two or more input and it will give a response as a result).
I need to create a system like work with websocket and ssh. When a websocket received a command ,ssh node need to execute this message and Module need to send it's response via websocket.send()
I am using Node.js websocket,ssh2 client.
Here my code :
#!/usr/bin/node
var Connection = require('ssh2');
var conn = new Connection();
var command="";
var http = require('http');
var WebSocketServer = require('websocket').server;
var firstcom=true;
conn.on('ready', function() {
console.log('Connection :: ready');
// conn.shell(onShell);
});
var onShell = function(err, stream) {
// stream.write(command+'\n');
stream.on('data', function(data) {
console.log('STDOUT: ' + data);
});
stream.stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
}
var webSocketsServerPort=5000;
var ssh2ConnectionControl=false;
var server = http.createServer(function (req, res) {
//blahbalh
}).listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port:: " + webSocketsServerPort);
});
//console.log((new Date()) + 'server created');
wsServer = new WebSocketServer({
httpServer: server,
// autoAcceptConnections: false
});
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
var wsconnection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
if(!ssh2ConnectionControl){
conn.connect({
host: 'localhost',
port: 22,
username: 'attilaakinci',
password: '1'
});
ssh2ConnectionControl=true;
console.log('SSH Connected.');
}
wsconnection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
command=message.utf8Data;
//if(firstcom){
// conn.shell(onShell);
// firstcom=false;
//}else{
conn.exec(message.utf8Data,onShell);
//}
wsconnection.send(message.utf8Data);
}
else{
console.log('Invalid message');
}
});
wsconnection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + wsconnection.remoteAddress + ' disconnected.');
});
});
You should use conn.shell() instead of conn.exec() if you want a real interactive shell. conn.exec() is typically for executing one-liner commands, so it does not persist "shell state" between conn.exec() calls (e.g. working directory, etc.).
You should also be aware of possible limits by your SSH server has set up as far as how many simultaneous shell/exec requests are allowed per connection. I think the default limit for this on OpenSSH's server is 10.
This is an old question but I wanted to provide a alternative method usings sh2shell which wraps ssh2.shell by mscdex, used above. The example below only covers making the ssh connection, running the commands and processing the result.
Using ssh2shel it is possible to run any number of commands sequentually in the context of the previous commands in the same shell session and then return the output for each command (onCommandComplete event) and/or return all session text on disconnection using a callback function.
See the ssh2shell readme for examples and lots of info. There are also tested scripts for working code examples.
var host = {
//ssh2.client.connect options
server: {
host: 120.0.0.1,
port: 22,
userName: username,
password: password
},
debug: false,
//array of commands run in the same session
commands: [
"echo $(pwd)",
command1,
command2,
command3
],
//process each command response
onCommandComplete: function( command, response, sshObj) {
//handle just one command or do it for all of the each time
if (command === "echo $(pwd)"){
this.emit("msg", response);
}
}
};
//host object can be defined earlier and host.commands = [....] set repeatedly later with each reconnection.
var SSH2Shell = require ('ssh2shell');
var SSH = new SSH2Shell(host),
callback = function( sessionText ){
console.log ( "-----Callback session text:\n" + sessionText);
console.log ( "-----Callback end" );
}
SSH.connect(callback)
To see what is happening at process level set debug to true.

Categories