I created a TCP server for receiving information from some devices, and I wanted to created an API out from this server, and I exported two variables in order to use them in the API.
When I do that, my server starts in my other process, making that they execute at the same time, I don't know why this happens
//server.js
const { title, BL_url, puerto_controladores, puerto_api } = require('...')
process.title = title;
var net = require('net');
var sockets = [];
var socketsID = [];
var lastConnected = [];
var server = net.createServer( function (socket) {
socket.name = socket.remoteAddress + ":" + socket.remotePort;
sockets.push(socket);
socketsID.push(socket.name.substr(7));
console.log(socket.name + ' connected.');
socket.on('data', (data) => {
textChunk = data.toString('utf8').substr(1,data.toString('utf8').length-2);
console.log('Mensaje de ' + socket.name.substr(7) +
socket.on('close', () =>{
console.log(socket.name + " desconectado.");
});
socket.on('error', (error) =>{
console.log('Error del Cliente TCP: ' + puerto_controladores, error.code, error.message);
});
});
server.on('error', (error) => {
console.log('Error del Server TCP: ' + puerto_controladores, error.message);
});
server.listen(puerto_controladores, ()=>{
setInterval(() => {
webMethods.sendInterval();
}, 180000);
console.log("Server listening at : " + puerto_controladores);
});
//setInterval(()=>{
module.exports = {sockets,socketsID};
On the other hand:
const {sockets,socketsID} = require('..server.js');
const {titleProcess,port} = require('...');
process.title = titleProcess;
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.listen(port, () => {
console.log('Listening at :',port);
});
app.get('/',(req,res)=>{
console.log(test.sockets,test.socketsID);
res.status(200).json({
mensaje: 'received',
})
})
Whatever I do in the server.js, a print of module.export, a new variable, including the title of process in command prompt etc. it runs in the API.js console
//API Output:
Server listening at : 9006
Listening at : 4002
{ sockets: [], socketsID: [] }
{ sockets: [], socketsID: [] }
//Server Output:
Error del Server TCP: 9006 listen EADDRINUSE: address already in use :::9006
Well socket objects in nodejs belong to a particular process. You can't just share them with another process easily. If you want one process to cause data to be sent on a socket the other process owns, then send the data itself to the other process using a different server and send some identifier with the data that the receiving process can use to figure out which socket the data should be sent to and it will then send the data over the socket it has. But, this whole thing sounds like a really confusing way to do things.
For example, let's say you have serverTCP (the plain TCP server from your server.js) and serverAPI (an Express server from your other file) each in separate processes. Put a separate Express server in serverTCP running on a local port, not open to the outside world. When serverAPI receives some data for some socketID, it then makes an http request to serverTCP and sends the data and the socketID. serverTCP receives that http request, gets the socketID and the data out of that request and sends it out over the appropriate socket it has a connection to.
FYI, this is generically known as a proxy where your API is somewhat serving as a proxy for the real socket connection. There are all sorts of modules in NPM that implement actual proxies too.
Related
Suppose that i have two of applications which is written below:
server.js
const express = require('express');
const app = express();
const WebSocketServer = require('ws');
var http = require('http');
let server = http.createServer(app).listen(8000);
const wss = new WebSocketServer.Server({ server: server })
// Creating connection using websocket
wss.on("connection", (ws, req) => {
console.log("req.socket.localPort = ", req.socket.localPort);
console.log("req.socket.remotePort = ", req.socket.remotePort);
console.log("req.socket.remoteAddress = ", req.socket.remoteAddress);
console.log("new client connected");
// sending message
ws.on("message", data => {
console.log(`Client has sent us: ${data}`)
});
// handling what to do when clients disconnects from server
ws.on("close", () => {
console.log("the client has connected");
});
// handling client connection error
ws.onerror = function () {
console.log("Some Error occurred")
}
});
and i have a "client" with same code base (code example) which listens port 8001.
Undoubtly, client's open address is 'ws://localhost:8001' and server's 'ws://localhost:8000'. When i make request to server from client,
console.log("req.socket.remotePort = ", req.socket.remotePort);
prints different ports after each message sending. But i want to get the number of 8001. How i can get the number of client's actual port of 8001?
Hello I have two backends laravel and Nodejs
and There will be one frontend.
So if the front end requests something on laravel and laravel requests to node and Node has to send a message to the client through WebSocket.
How to do It?
Index.js
const app = require('express')();
const http = require('http');
const WebSocket = require('ws')
//initialize a simple http server
const server = http.createServer(app);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
let sendNotification;
//initialize the WebSocket server instance
const wss = new WebSocket.Server({ server });
let socketapi = require('./socketapi')
socketapi.start(wss)
//start our server
server.listen(process.env.PORT || 5555, () => {
console.log(`Server started on port ${server.address().port} :)`);
});
socketapi.js
module.exports ={
start: (wss) => {
wss.on('connection', (ws) => {
console.log('connected!!!');
console.log(socketIds)
//connection is up, let's add a simple simple event
// triggerMessage('data');
ws.id=uuidv4()
ws.on('message', (message) => {
console.log('received: %s', message);
// ws.send(`Hello, you sent -> ${message}`);
});
}
}
}
Now I want to use this socket in the controller file and send it as I get a request.
When I export and import socket it logs as undefined.
I have stored and ws in array with particular Id and that Id was associated with data in DB so I can use that Id to get ws and send through that ws on function calling
I am trying to build a two way socket.io server/client connection. The server will remain behind one IP/domain and the client will behind a different IP. The point is to notify me when the server goes offline, in case of power outage or server failure. The issue I am having, is I am trying to secure the socket so not just anyone can connect to the socket. Socket.IO has a server.origins function that will return the origin of socket trying to connect. Their API documentation explains it like this.
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
The issue I am having is whenever I connect to the socket.io server with socket.io-client the origin is always '*'.
Under potential drawbacks in there API is says:
"in some situations, when it is not possible to determine origin it may have value of *"
How do I get socket.io it see the IP where the socket connection request is coming from?
Once the connection is established I can use the socket information and see the IP where the socket lives, but the connection is already made. I am trying to stop rouge connections.
# Server
const express = require('express');
const app = express();
const chalk = require('chalk')
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const cors = require('cors');
const port = 4424;
app.use(cors());
io.origins((origin, callback) => {
console.log(origin);
if (origin !== '*') {
return callback('origin not allowed', false);
}
callback(null, true);
});
io.on('connection', (socket) => {
console.log('Client connected...');
socket.on('join', (data) => {
console.log(data);
socket.emit('messages', 'Hello from server');
});
})
server.listen(port, () => console.log(chalk.blue(`Express started on port ${port}!`)));
Client:
# Client
const io = require('socket.io-client');
const socket = io('https://"MY DOMAIN THAT THE SERVER IS BEHIND"', { reconnect: true })
socket.on('connect', (data) => {
console.log("Connection successful");
socket.emit('join', 'Hello World from client');
});
socket.on('connect_error', (error) => {
console.log("Connection error");
});
socket.on('disconnect', (timeout) => {
console.log("Connection disconnected");
})
socket.on('messages', (data) => {
console.log(data);
});
I have the server behind a NGINX server using SSL, and connected to the server with the client on a different IP and it goes through and creates the connection, but the Origin is always "*".
Actually I found out you can use middleware with Socket.io with the io.use() function. I just wrote a simple middleware that checks the incoming socket ip with a list of approved ips.
io.use((socket, next) => {
const ip = socket.handshake.headers['x-forwarded-for']
if (firewall(ip))
{
return next();
}
})
And firewall is a function that checks if the ip is in the array of approved ips.
I am working on a node JS application, where I am trying to use socket.io following this tutorial. Until this tutorial everything is fine, even the client is connected to the server through the socket, as it display a message on connection. But I don't know why my code isn't working on emit, and on event, and event handler.
Below is my Code on server side :
const express = require("express");
const app = express();
const scrap = require("./algorithm");
const mysql = require("mysql");
const ms_connect = mysql.createConnection({
host:'localhost',
user:'root',
password:'',
database:'scrapper_db'
});
const server = app.listen(8000, function(){ console.log('Listening on 8000'); });
const io = require("socket.io").listen(server);
app.use(express.static(__dirname + "/"));
io.on("connection",function(socket){
console.log("Sockets Connection Made ! " + socket.id);
socket.emit("testing",{data:"I am tested"});
io.on("disconnect",function(){
console.log("Client Disconnected !");
})
})
//mySQL Conection
ms_connect.connect(function(err){
if(err) console.log(err);
ms_connect.query("Select * FROM test",function(err,rows,fields){
if(err) console.log("Error Executing Query");
})
})
app.get("/scrap",function(req,res){
res.sendFile(__dirname+"/index.html");
})
Client side code :
var socket = io.connect('http://localhost:8000/scrap');
console.log(socket.connected); //returns false :(
socket.on("testing", function(d) {
console.log(d);
});
In the client side, the socket.connected object returns false, but on server side it says connected. I don't know how , and
I am using third link from this socket.io cdnjs server.
You are doing io.connect('http://localhost:8000/scrap') but the scrap is not mentioned anywhere on the server side. It should be io.connect('http://localhost:8000/'). Pointing to your HTML file is not needed because the socket.io server and your webserver are unrelated.
Also as pointed out by #TommyBs you should use
socket.on('connect', () => { console.log(socket.connected); });
to check if you are connected because connecting is asynchronous so it will not have connected yet by the time you do console.log(socket.connected);
The whole client code would be
var socket = io.connect('http://localhost:8000');
socket.on('connect', () => { console.log(socket.connected); });
socket.on("testing", function(d) {
console.log(d);
});
Change http://localhost:8000/scrap to http://localhost:8000/ in the client code. You're connecting to the wrong route.
I am having a problem of using socket IO to connect my server to the client(http website).
On the client, I have a button that when pressed, sends data to the server. However, this only works with one client.
If I have two clients, the first person to open the http website gets the socket IO connection, while the second person can open the page, but can't send any data to the server.
On the client side:
var socket = new io.connect('ServerIP:8090');
socket.on('message', function(obj){
if ('buffer' in obj){
//ignore this
} else message(obj);
});
On server side:
var io = io.listen(server)
, buffer = [];
io.on('connection', function(client)
{
client.send({ buffer: buffer });
client.broadcast.send({ announcement: client.sessionId + ' connected' });
chatGuests.push(client);
client.on('message', function(message){
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.broadcast.send(msg);
});
client.on('disconnect', function(){
client.broadcast.send({ announcement: client.sessionId + ' disconnected' });
});
Instead of using client.broadcast.send(something) and client.send(something) use io.emit('eventName', something). Also, for setting up the server with the variable io use
var socket = require('socket.io');
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = socket.listen(server);
And then after your code:
server.listen(8090);
This allows you to use the node.js module express, which allows additional communication between the client and server (but doesn't require you to rewrite your socket.io code).
For your client code, instead of using:
socket.on('message', function(obj){
//Do something
});
Use:
socket.on('eventName', function(something){
//Do something
});
This works for multiple kinds of data passing, not just messages. You can multiple event listeners to each do different things