Can't send call to client - node.js

I can not get the module to send the Server Call Data to the client (see line 36) so that the client can then return the sensor data.
I have run out of ideas, have tried lots of things.
Also if I uncomment 'use strict' why is console.log called as an error?
Note : I have included fhe file .jshintrc in the development directory to ensure ES6 is validated.
The code is as follows;
// See https://techbrij.com/node-js-tcp-server-client-promisify
//'use strict';
const ServerComms = { // Server Comms Data
serverIP :"192.168.100.199",
serverPort : 9000
}; // End ClientComms
var ClientComms = { // Client Comms Data
clientIP :"192.168.100.101",
clientPort : 9000
}; // End ClientComms
var ServerCall = { // Server job call to client
clientIP : ClientComms.clientIP, // '192.168.100.101', Same as ClientComms.clientIP
jobID : 1
}; // End ServerCall
const net = require('net');
class MyServer {
constructor() {
this.address = ServerComms.serverIP;
this.port = ServerComms.serverPort;
this.init();
} // End constructor
init() {
let server = this;
let onClientConnected = (socket) => {
console.log(`Sending request job to RSU : ${ServerComms.serverPort} ${ServerComms.serverIP}`);
server.socket.write( ServerCall.clientIP, ServerCall.jobID ); // Send request and data to client so that client can respond with remote sensor data.
let clientName = `${ClientComms.clientIP} : ${ClientComms.clientPort}`;
console.log(`New client is connected: ${clientName}`);
socket.on('data', (clientData) => {
console.log(`${clientName} Says: ${clientData}`);
socket.write(clientData);
socket.write('exit');
});
socket.only('close', () => {
console.log(`Connection from ${clientName} closed`);
});
socket.on('error', (err) => {
console.log(`Connection ${clientName} error: ${err.message}`);
});
}; // End onClientConnect.
//server.connection = net.createServer(onClientConnected);
server.connection = net.createServer( onClientConnected, function(){
console.log(`Server created at: ${ServerComms.serverIP} : ${ServerComms.serverPort}`);
});
server.connection.listen(ServerComms.serverPort, ServerComms.serverIP, function() {
console.log(`Server started at: ${ServerComms.serverIP} : ${ServerComms.serverPort}`);
}); // End server.connection.listen
} // End init
} // End class Server
module.exports = MyServer;
The calling module is as follows;
// To test server, use following code in another file and run it
const Server = require('./ServerCommsV05.js');
new Server();

Related

reconnecting to nodejs websocket on failure

This is my first practice after reading some tutorials and videos. Basically, I need message to be sent from the server (nodejs) to the client (Angular 6). At first tho, when client app is booted, it sends user id to the server for authentication. The server then will send data based on that user.
Now my problem is on first load and a few calls, the connection does work. But then on refresh or so, the connection drops. My client does console out "retrying" but it never succeeds. It works only if I manually restart the server and reload the client so a new connection could be established.
How can I maintain a fairly stable connection throughout the lifetime of a client? At times the readyState stays at 3 on the server i.e. connecting, which I am confused with because the client does try to reconnect...just fails.
My Server is simple. index.js (Tried to put it up on stackblitz but failed...would appreciate if someone can figure out the dependency file: nodejs websocket server)
const express = require('express');
const bodyParser = require('body-parser');
const pg = require ('pg');
var ws = require('./ws')
var app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(3000, function () {
console.log('We are running on port 3000!')
})
ws.js:
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.File({ filename: 'error.log'})
]
});
var WebSocketServer = require("ws").Server,
wss = new WebSocketServer({
port: 40511
});
let data = {
'packet': ['amy1', 'amy2', 'amy3']
}
const mx = 2;
const mn = 0;
wss.on("connection", function(ws) {
ws.on("message", function(user) {
// client has called now. If the connection
// fails, the client does try to connection again and again -- no limit but it simply doesn't seem to have effect. When connecting, it simply sends user name
console.log("received: %s", user);
setInterval(function(){
var random = Math.floor(Math.random() * (mx - mn + 1) + mn);
if (ws.readyState == ws.OPEN){
ws.send(data['packet'][random]);
}
}, 3000);
});
});
My front end is: service.ts
import { Observable} from 'rxjs';
export class WebSocketService {
socket: WebSocket;
constructor() { }
initConnection(): void {
if(!this.socket){
this.socket = new WebSocket('ws://localhost:40511');
// when connection is open, send user id
this.socket.onopen = () => this.socket.send(2);
}
}
manageState() : Observable<any>{
const vm = this;
return new Observable(observer => {
this.socket.onerror = (e) => {
// close it
this.socket.close();
observer.next('web socket communication closed due to error')
};
this.socket.onclose = (e) => {
//socket closed for any reason
setTimeout(function() {
console.log('try to connect')
vm.initConnection();
observer.next('still trying')
}, 1000);
}
});
}
onMessage(): Observable<any> {
// when message arrives:
return new Observable(observer => {
this.socket.onmessage = (e) => {
console.log(e.data);
observer.next(e.data)
};
});
}
}
component.ts:
// initialize the connection
this.service.initConnection();
this.service.onMessage().subscribe(
data => {
// we have got data
console.log('data came ', data)
},
err => {
console.log("error websocking service ", err);
}
);
// track state of the communication, letting the service to reconnect if connection is dropped
this.service.manageState().subscribe(data => {
console.log(data);
});

Readline parser doesn't read correctly from serial port - NodeJS

I have a connection with POS (point of sale) device. I send it information in hex code and the device prints a receipt.
My problem is that the parser (Readline) doesn't work. When I try to use parser.on("data", console.log), it doesn't return anything.
Here is my code:
const SerialPort = require('serialport');// include the library
const WebSocketServer = require('ws').Server;
const SERVER_PORT = 7000; // port number for the webSocket server
const wss = new WebSocketServer({port: SERVER_PORT}); // the webSocket server
var connections = new Array; // list of connections to the server
const Readline = SerialPort.parsers.Readline;
wss.on('connection', handleConnection);
const myPort = new SerialPort("COM3", {
baudRate: 115200,
});
myPort.on('open', showPortOpen);
myPort.on('close', showPortClose);
myPort.on('error', showError);
const parser = myPort.pipe(new Readline('\r\n'))
console.log('parser setup');
parser.on('data', function(data) {
console.log('data received: ', data);
});
function handleConnection(client) {
console.log("New Connection"); // you have a new client
connections.push(client); // add this client to the connections array
client.on('message', sendToSerial); // when a client sends a message,
client.on('close', function() { // when a client closes its connection
console.log("connection closed"); // print it out
var position = connections.indexOf(client); // get the client's position in the array
connections.splice(position, 1); // and delete it from the array
});
}
function sendToSerial(data) {
console.log("sending to serial: " + data);
myPort.write(data, 'hex');
}
// This function broadcasts messages to all webSocket clients
function broadcast(data) {
console.log(data);
for (myConnection in connections) { // iterate over the array of connections
connections[myConnection].send(JSON.stringify(data)); // send the data to each connection
}
}
function showPortOpen() {
console.log('port open. Data rate: ' + myPort.baudRate);
}
function readSerialData(data) {
// if there are webSocket connections, send the serial data
// to all of them:
if (connections.length > 0) {
broadcast(data);
}
}
function showPortClose() {
console.log('port closed.');
}
function showError(error) {
console.log('Serial port error: ' + error);
}
I receive messages, but they are split and I want to send to client whole message. I tried to define the parser and after that to pipe it. I tried to set parser in SerialPort constructor, changed the delimiter, but no result.
I think that my error is something with the parser.
Here you can see that doesn't return console.log
And here is the result if I use
myPort.on('data', function(data) {
console.log('data received: ', data);
});
The idea is to get whole message after every command and send it to the client.
Use the built-in readline api from SerialPort:
const SerialPort = require('serialport');// include the library
const WebSocketServer = require('ws').Server;
const SERVER_PORT = 7000; // port number for the webSocket server
const wss = new WebSocketServer({port: SERVER_PORT}); // the webSocket server
var connections = new Array; // list of connections to the server
const Readline = SerialPort.parsers.Readline;
wss.on('connection', handleConnection);
const myPort = new SerialPort('COM3', {
baudRate: 115200,
parser: SerialPort.parsers.readline('\r\n')
});
myPort.on('open', showPortOpen);
myPort.on('close', showPortClose);
myPort.on('error', showError);
myPort.on('data', data => readSerialData(data.toString());
// ...
function broadcast(data) {
console.log(data);
for (myConnection in connections) {
connections[myConnection].send(JSON.stringify(data));
}
}
// ...
function readSerialData(data) {
// if there are webSocket connections, send the serial data
// to all of them:
if (connections.length > 0) {
broadcast(data);
}
}
// ...
The message is split again. So I want it whole message to decode it by hex code. Did the problem come from parser?

Simple Access-Control-Allow-Origin with net module

I have two servers one on port 80 which is a normal web server and than one on port 8080 that is a broadcast server that sends a text string with all the updates to show. However the browser gives me a CORS header 'Access-Control-Allow-Origin' missing. And is it any simple way for me to add the header with the net package? The server code looks as following:
Code to create the server:
var net = require('net');
var fs = require('fs');
var buffer = require('buffer');
var serverHost = "0.0.0.0";
var serverPort = 8080;
var splitter = require('./splitter.js');
var server = net.createServer(function(target) {
// Socket errors
target.on('error', function(error) {
console.log('Socket error: ', error.message);
});
target.on('data', function(data){
// TODO: Verify the data
var number = parseInt(data);
if(!isNaN(number)){
// Adds the client to the list
splitter.addClient(target, number);
}
else{
target.write("Match ID is not correctly formatted");
}
});
});
// Listening for any problems with the server
server.on('error', function(error) {
console.log("Error listening to the server!", error.message);
});
server.listen(serverPort, serverHost);
splitter code (Add client and send data):
var gameids = {1337:[]}
function addClient(client, gameID){
if(matchExists(gameID)){
console.log("Client", client.remoteAddress, "begun watching gameID", gameID,"\n");
var id = gameids[gameID].push(client);
}
else{
client.write("A match with the given ID does not exists");
}
}
function sendData(data, gameID){
if(gameids[gameID].length > 0){
for(i = 0; i < gameids[gameID].length;i++){
console.log(gameids[gameID][i]);
if(gameids[gameID][i].writable){
console.log("Sent data");
gameids[gameID][i].write(data);
}
}
}
}
The function send data is called from my main script which just takes the input from another server and then sends that out to all clients watching.

Having Difficulties in Integrating a Simple Code Snippet into a Complex Existing Node.js Code

I am trying to add a new URL path (Node.js home page has given an example to do it.) to a piece of complex existing code (shown below). The existing code already has server configuration code but the code looks very different from the "Building a Node.js Web Server" example that is showing in the Node.js home page.
The new URL path is "/lens/v1/ping" that is sent from the browser window.
If that is the URL path received, I am supposed to send a response Status 200 back to the browser.
I am having difficulties to fit this new URL path and its associated code to the existing code (show below) and I am seeking help. Thank you very much.
/**
* Entry point for the RESTFul Service.
*/
var express = require('express')
var config = require('config');
var _ = require('underscore');
var bodyParser = require("vcommons").bodyParser;
// Export config, so that it can be used anywhere
module.exports.config = config;
var Log = require('vcommons').log;
var logger = Log.getLogger('SUBSCRIBE', config.log);
var http = require("http");
var https = require("https");
var fs = require("fs");
var cluster = require("cluster");
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('online', function (worker) {
logger.info('A worker with #' + worker.id);
});
cluster.on('listening', function (worker, address) {
logger.info('A worker is now connected to ' + address.address + ':' + address.port);
});
cluster.on('exit', function (worker, code, signal) {
logger.info('worker ' + worker.process.pid + ' died');
});
} else {
logger.info("Starting Subscription Application");
createApp();
}
// Create Express App
function createApp() {
var app = express();
app.configure(function () {
// enable web server logging; pipe those log messages through winston
var winstonStream = {
write : function (message, encoding) {
logger.trace(message);
}
}; // Log
app.use(bodyParser({}));
app.use(app.router);
if (config.debug) {
app.use(express.errorHandler({
showStack : true,
dumpExceptions : true
}));
}
});
// Include Router
var router = require('../lib/router')();
// Subscribe to changes by certain domain for a person
app.post('/lens/v1/:assigningAuthority/:identifier/*', router.submitRequest);
// Listen
if (!_.isUndefined(config.server) || !_.isUndefined(config.secureServer)) {
if (!_.isUndefined(config.server)) {
http.createServer(app).listen(config.server.port, config.server.host, function () {
logger.info("Subscribe server listening at http://" + config.server.host + ":"
+ config.server.port);
});
}
if (!_.isUndefined(config.secureServer)) {
https.createServer(fixOptions(config.secureServer.options), app).listen
(config.secureServer.port, config.secureServer.host, function () {
logger.info("Subscribe server listening at https://" + config.secureServer.host
+ ":" + config.secureServer.port);
});
}
} else {
logger.error("Configuration must contain a server or secureServer.");
process.exit();
}
}
function fixOptions(configOptions) {
var options = {};
if (!_.isUndefined(configOptions.key) && _.isString(configOptions.key)) {
options.key = fs.readFileSync(configOptions.key);
}
if (!_.isUndefined(configOptions.cert) && _.isString(configOptions.cert)) {
options.cert = fs.readFileSync(configOptions.cert);
}
if (!_.isUndefined(configOptions.pfx) && _.isString(configOptions.pfx)) {
options.pfx = fs.readFileSync(configOptions.pfx);
}
return options;
}
// Default exception handler
process.on('uncaughtException', function (err) {
logger.error('Caught exception: ' + err);
process.exit()
});
// Ctrl-C Shutdown
process.on('SIGINT', function () {
logger.info("Shutting down from SIGINT (Crtl-C)")
process.exit()
})
// Default exception handler
process.on('exit', function (err) {
logger.info('Exiting.. Error:', err);
});
A browser window executes a HTTP GET request. After the // Include Router call, that is where you would define your express GET function.
...
// Include Router
var router = require('../lib/router')();
//*********
//define your method here, as shown, or in your router file.
app.get('lens/v1/ping', function(req, res){
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end();
} );
//*********
// Subscribe to changes by certain domain for a person
app.post('/lens/v1/:assigningAuthority/:identifier/*', router.submitRequest);
...

WebRTC Video sharing app doesn't work

I have been trying to share a video stream between two clients over WebRTC for about a week now and I have no idea how to proceed any further. I'm frustrated and could really use some help from the more experienced. Please help me get this running.
I am using Websockets and NodeJS. I will post all of my code below:
Server Code ( on NodeJS )
"use strict";
/** Requires **/
var webSocketServer = require('websocket').server,
expr = require("express"),
xpress = expr(),
server = require('http').createServer(xpress);
// Configure express
xpress.configure(function() {
xpress.use(expr.static(__dirname + "/public"));
xpress.set("view options", {layout: false});
});
// Handle GET requests to root directory
xpress.get('/', function(req, res) {
res.sendfile(__dirname + '/public/index.html');
});
// WebSocket Server
var wsServer = new webSocketServer({
httpServer: server
});
// Set up the http server
server.listen(8000, function(err) {
if(!err) { console.log("Listening on port 8000"); }
});
var clients = [ ];
/** On connection established */
wsServer.on('request', function(request) {
// Accept connection - you should check 'request.origin' to make sure that client is connecting from your website
var connection = request.accept(null, request.origin);
var self = this;
// We need to know client index to remove them on 'close' event
var index = clients.push(connection) - 1;
// Event Listener for when Clients send a message to the Server
connection.on('message', function(message) {
var parsedMessage = JSON.parse(message.utf8Data);
if ( parsedMessage.kind == 'senderDescription' ) {
wsServer.broadcastUTF(JSON.stringify({ kind:'callersDescription', callerData: parsedMessage }));
}
});
});
Index.html loads and immediately runs VideoChatApp.js
function VideoChatApp() {
this.connection = null;
this.runConnection();
}
_p = VideoChatApp.prototype;
/** Initialize the connection and sets up the event listeners **/
_p.runConnection = function(){
// To allow event listeners to have access to the correct scope
var self = this;
// if user is running mozilla then use it's built-in WebSocket
window.WebSocket = window.WebSocket || window.MozWebSocket;
// if browser doesn't support WebSocket, just show some notification and exit
if (!window.WebSocket) { return; }
/** Where to make the connection **/
var host = location.origin.replace(/^http/, 'ws');
console.log(host);
this.connection = new WebSocket(host);
/** Once the connection is established **/
this.connection.onopen = function () {
console.log("Web Socket Connection Established");
self.onConnectionEstablished();
};
/** If there was a problem with the connection */
this.connection.onerror = function (error) {
console.log("ERROR with the connection *sadface*");
};
}; // end runConnection
_p.onConnectionEstablished = function() {
// My connection to the nodejs server
var websocketConnection = this.connection;
// Some local variables for use later
var mediaConstraints = {
optional: [],
mandatory: {
OfferToReceiveVideo: true
}
};
var offerer, answerer;
this.theLocalStream = null;
var amITheCaller = false;
var localVideoTag = document.getElementById('localVideoTag');
var remoteVideoTag = document.getElementById('remoteVideoTag');
window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.URL = window.webkitURL || window.URL;
window.iceServers = {
iceServers: [{
url: 'stun:23.21.150.121'
}]
};
var callButton = document.getElementById("callButton");
callButton.onclick = callClicked;
function callClicked() {
amITheCaller = true;
setUpOffer();
}
offerer = new RTCPeerConnection(window.iceServers);
answerer = new RTCPeerConnection(window.iceServers);
/** Start Here - Set up my local stream **/
getUserMedia(function (stream) {
hookUpLocalStream(stream);
});
function getUserMedia(callback) {
navigator.getUserMedia({
video: true
}, callback, onerror);
function onerror(e) {
console.error(e);
}
}
function hookUpLocalStream(localStream) {
this.theLocalStream = localStream;
callButton.disabled = false;
localVideoTag.src = URL.createObjectURL(localStream);
localVideoTag.play();
};
/* When you click call, then we come here. Here I want to set up the offer and send it. */
function setUpOffer() {
var stream = theLocalStream;
offerer.addStream(stream);
offerer.onaddstream = function (event) {
console.log("onaddstream callback was called");
};
offerer.onicecandidate = function (event) {
if (!event || !event.candidate) return;
answerer.addIceCandidate(event.candidate);
};
offerer.createOffer(function (offer) {
offerer.setLocalDescription(offer);
console.log("------------------- What I am sending: -------------------------");
console.log(offer);
console.log(stream);
console.log("-----------------------------------------------------------------\n");
var jsonMsg = JSON.stringify( {kind:'senderDescription', streamInfo: offer, theStream: stream} );
websocketConnection.send( jsonMsg );
//answererPeer(offer, stream);
}, onSdpError, mediaConstraints);
}
/* Respond to a call */
function answererPeer(offer, stream) {
answerer.addStream(stream);
answerer.onaddstream = function (event) {
remoteVideoTag.src = URL.createObjectURL(event.stream);
remoteVideoTag.play();
};
answerer.onicecandidate = function (event) {
if (!event || !event.candidate) return;
offerer.addIceCandidate(event.candidate);
};
answerer.setRemoteDescription(offer, onSdpSucces, onSdpError);
answerer.createAnswer(function (answer) {
answerer.setLocalDescription(answer);
offerer.setRemoteDescription(answer, onSdpSucces, onSdpError);
}, onSdpError, mediaConstraints);
}
function onSdpError(e) {
console.error('onSdpError', e);
}
function onSdpSucces() {
console.log('onSdpSucces');
}
websocketConnection.onmessage = function (messageFromServer) {
console.log(" ------------------------ Message from server: -------------------- ");
var parsedMessage = JSON.parse(messageFromServer.data);
if(parsedMessage.callerData.kind = "senderDescription") {
console.log("Received a senderDescription");
console.log(parsedMessage.callerData.streamInfo);
console.log(parsedMessage.callerData.theStream);
console.log("-------------------------------------------------------------------\n");
answererPeer(parsedMessage.callerData.streamInfo, parsedMessage.callerData.theStream);
}
};
};// end onConnectionEstablished()
Finally, here are my errors:
I am not sure if this is still interesting for you, but I have some very good experience with WebRTC using PeerJS as a wrapper around it. It takes care of all the stuff you don't want to do (http://peerjs.com/). There is the client library as well as a very nice signaling server for nodejs (https://github.com/peers/peerjs-server). You can easy extend this server in your own node server.
This may not explain why your approach failed, but gets WebRTC running easily.
You can start with code that is already working and completely open. Check out easyrtc.com we have a client api, signalling server and working code. And if you have problems with that code ask us for help on Google Groups for easyrtc.

Resources