I'm having trouble connecting 4 arduinos using serialports and NodeJs.
When I connect all the ports only one is actually working and collecting the data message while all the others are ignored.
If I declare the serial ports separately they all work fine so the problem is not the Arduino code.
Here's how i declare all the serialports:
// Load HTTP module to create server, handle requests and send back static files (html, css, js)
const http = require('http');
// Load file system module to load files from computer
const fs = require('fs');
// Load path module to read paths from urls
const path = require('path');
// Load serialport module to communicate with arduino
const SerialPort = require('serialport');
// Open up connection with Arduino board
const serial = new SerialPort('/dev/cu.usbserial-1411140', {
baudRate: 115200
}, function() {
console.log('1411140 ready');
})
const SerialPort1 = require('serialport');
const serial1 = new SerialPort1('/dev/cu.usbserial-141120', {
baudRate: 115200
}, function() {
console.log('141120 ready');
})
const SerialPort2 = require('serialport');
const serial2 = new SerialPort2('/dev/cu.usbmodem-1411301', {
baudRate: 115200
}, function() {
console.log('1411301 ready');
})
const SerialPort3 = require('serialport');
const serial3 = new SerialPort3('/dev/cu.usbserial-1411130', {
baudRate: 115200
}, function() {
console.log('1411130 ready');
})
// Define port on which the webpage will be served from
const port = 8080;
This is how i read the arduino data
const io = require('socket.io')(server);
// do stuff when a client connects
io.on('connection', (socket) => {
console.log('a new client connected');
// let the client know that it's connected
socket.emit('greetings', 'You are now connected to the server through Socket IO');
// when receiving data from Arduino, tell the client what to do accordingly
serial.on('data', forwardMessage);
// log if an user disconnects
socket.on('disconnect', () => {
console.log('client disconnected');
// remove listener from Node EventEmitter
serial.removeListener('data', forwardMessage);
});
function forwardMessage(data) {
let message = data.toString().replace(/\n*/, '');
//riceve messaggi dal device corrispondente. Attenzione al nome messo anche sul codice Arduino
if (message.includes('Coinv')) {
socket.emit('CoinvChange', message.substring(7));
}
if (message.includes('Impor')) {
socket.emit('ImporChange', message.substring(7));
}
if (message.includes('Piace')) {
socket.emit('PiaceChange', message.substring(7));
}
if (message.includes('Cresc')) {
socket.emit('CrescChange', message.substring(7));
}
if (message.includes('Press')) {
socket.emit('PressChange', message.substring(7));
}
}
});
And finally this is how i use the message
const socket = io();
// log on browser console when socket is connected to server
socket.on('greetings', (message) => {
console.log(message);
});
// Caricamento Petali
socket.on('CoinvChange', (message) => {
console.log('coinv');
if(message<=6){
getFlowerObject ("petali", 1);
}
if(message>7 && message <=9) {
getFlowerObject ("petali", 2);
}
if(message>12) {
getFlowerObject ("petali", 3);
}
});
// Caricamento Sepali
socket.on('ImporChange', (message) => {
console.log('Impor');
if(message<=2){
getFlowerObject ("sepali", 1);
}
if(message>3 && message <=7) {
getFlowerObject ("sepali", 2);
}
if(message>8) {
getFlowerObject ("sepali", 3);
}
});
Thank you for your help!
Well, in the second snipped, you call just serial.on('data', forwardMessage);, and serial just refers to the firt one.
If you want to interact with the other ones, you have to call the same method also on serial1, serial2 and serial3, which you never use, instead.
As a sidenote, it's enugh to use const SerialPort = require('serialport'); just at the beginning (of the first snippet), then you can do
const serial1 = new SerialPort(...)
...
const serial2 = new SerialPort(...)
...
Related
My code is working fine when new user joins but when a user left it doesn't show anything
Can anyone tell me error in my code
Here is my server side code
const express = require("express");
const path = require("path");
const http = require("http");
const socketio = require("socket.io");
const app = express();
const server = http.createServer(app);
const io = socketio(server); // socketio expects to be called by raw http server so we did little bit of refactoring
const publicPath = path.join(__dirname, "../public");
const port = process.env.PORT || 3000;
app.use(express.static(publicPath));
// let count = 0;
// server(emit) -> client(receive) -> countUpdated
// client(emit) -> server(receive) -> increment
io.on("connection", (socket) => {
console.log("New web socket connection");
socket.emit("message", "Welcome!");
socket.broadcast.emit("message", "A new user has joined"); // it emits msg to everyone except the user who run this command
socket.on("sendMessage", (message) => {
io.emit("message", message);
socket.on("disconnect", () => {
io.emit("message", "A user has left");
}); // when user disconnect we use socket.on("disconnect")
});
Here is my client side code
const socket = io(); // to communicate with socketio we did this, now we can send events or recieve events from clients
socket.on("message", (message) => {
console.log(message);
});
const form = document.querySelector("#message-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
let message = e.target.elements.message.value; // e.target refers to form and we can select elements of form using the name property we defined in html
socket.emit("sendMessage", message);
});
I am expecting when a user left
It should show "A user has left" in console
Currently you have only start to listen to disconnect event when the client has already sent at least 1 message. Here's the relevant extract:
io.on("connection", (socket) => {
// …
socket.on("sendMessage", (message) => {
// …
socket.on("disconnect", () => {
});
});
});
You should therefore reduce the callback nesting, and start listening to disconnect in the connection handler directly. Which leads to:
io.on("connection", (socket) => {
console.log("New web socket connection");
socket.emit("message", "Welcome!");
socket.broadcast.emit("message", "A new user has joined"); // it emits msg to everyone except the user who run this command
socket.on("disconnect", () => {
io.emit("message", "A user has left");
}); // when user disconnect we use socket.on("disconnect")
socket.on("sendMessage", (message) => {
io.emit("message", message);
});
});
I am using nodejs to run the server, there is no log file
This is my server.js
const https = require('https');
const fs = require('fs');
const ws = require('ws');
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
const wss = new ws.Server({noServer: true});
function accept(req, res) {
// all incoming requests must be websockets
if (!req.headers.upgrade || req.headers.upgrade.toLowerCase() != 'websocket') {
res.end();
return;
}
// can be Connection: keep-alive, Upgrade
if (!req.headers.connection.match(/\bupgrade\b/i)) {
res.end();
return;
}
wss.handleUpgrade(req, req.socket, Buffer.alloc(0), onConnect);
}
function onConnect(ws) {
ws.on('message', function (message) {
let name = message.match(/([\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]+)$/gu) || "Guest";
ws.send(`${name}!`);
//setTimeout(() => ws.close(1000, "Bye!"), 5000);
});
}
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
This is my code in react
componentDidMount() {
var connection = new WebSocket('wss://localhost:8000/');
connection.onopen = function(e) {
connection.send("add people");
};
connection.onmessage = function(event) {
// alert(`[message] Data received from server: ${event.data}`);
console.log("output ", event.data);
};
}
While I am trying to connect with web-socket with my jsx file its give me an error which is Firefox can’t establish a connection to the server at wss://localhost:8000/.
Your implementaion needs some changes. In the backend server, you forgot to call the onConnect function. So your ws.on method will never call.
Also, you imported the ws and create a WebSocket server wss, but you add some event listener on ws wrongly, you should add listener on your Websocket instance (wss):
// rest of the codes ...
const was = new ws.Server({noServer: true})
wss.on('connection`) {
// do something here ...
}
// rest of the codes ...
https.createServer(options, () => {
// do something here ...
})
There are some examples of how to create the WebSocket server along with the HTTP server on ws npm page.
So what I am trying is to establish a socket.io connection between an express server and a react client. Maybe also mentionable the client is hosted on netlify and the server on heroku.
The actual problem is the client seems to connect and receives the upgrade protocol to websocket messages with a HTTP 101. But nothing else happens afterwards. No "connection" or "connected" event is emitted. Maybe some one spots a mistake in the code or can guide me to the solution.
Server
/**
* App Configuration
*/
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server, {
cors: {
origin: process.env.CLIENT_URL,
methods: ["GET", "POST"],
credentials: true
}
});
/**
* Socket IO
*/
io.on("connection", (socket: any) => {
console.log("Client Connected via Socket");
// Join a conversation
const { deviceId } = socket.handshake.query;
socket.join(deviceId);
// Leave the room if the user closes the socket
socket.on("disconnect", () => {
socket.leave(deviceId);
});
});
/**
* Server Activation
*/
app.listen(process.env.PORT, () => {
console.log(`Listening on port ${process.env.PORT}`);
});
Client
const socketRef = useRef();
useEffect(() => {
// Creates a WebSocket connection
socketRef.current = io(process.env.REACT_APP_API, {
transports: ['websocket'],
query: { deviceId: 'test-id' }
});
socketRef.current.on('connect', () => {
console.log("connected");
});
// Listens for incoming messages
socketRef.current.on("message", (message) => {
console.log(message);
});
// Destroys the socket reference
// when the connection is closed
return () => {
socketRef.current.disconnect();
};
}, []);
Edit:
Adding an image of the recurring http message about the websocket upgrade.
HTTP Message
Change Server activation line to below
server.listen(process.env.PORT, () => {
console.log(`Listening on port ${process.env.PORT}`);
})
I'm actually trying to make a real-time connection between two different apps. I've found a bunch of tutorials about how to make a chat using socket.io, but that doesn't really help me since it's just the same app duplicated in multiple windows.
I'm making a pick & ban overlay for League of Legends in local development. My first thought was to display the empty overlay on one hand and create an interface to manually update it on the other hand. Socket.io seems to be the right thing to use in my case since it can provide new data without having to reload the component.
This is what I wrote in both apps :
const express = require('express');
const socket = require('socket.io');
// App setup
const app = express();
const server = app.listen(4200, function () {
console.log('Listening to requests on port 4200')
});
// Static files
app.use(express.static('public'));
// Socket setup
const io = socket(server);
io.on('connection', function (socket) {
console.log('Made socket connection', socket.id);
socket.on('change', function (data) {
io.sockets.emit('change', data);
});
});
But I fail to connect them as they have to listen to the same port. What am I doing wrong?
(Forgive my bad English and lack of syntax, I'm doing my best here. :p)
I am certainly not an expert on network programming, but as far as I know you need to have one listening app (backend) and another one to connect to it (client). And you define what happens with all the data (messages) that backend recieves (for example sending the messages it recieves to all the clients in the same chat room).
If I am correct to assume you are trying to connect two listening apps?
simple google search of "nodejs socket server client example" revealed this https://www.dev2qa.com/node-js-tcp-socket-client-server-example/ might wanna take your research in this direction
u can try something like this way
var express = require('express');
var socket = require('socket.io');
// App setup
var app = express();
var server = app.listen(8080, () => {
console.log('App started')
})
// Static file
app.use(express.static('public'))
// Socket SetUp
var io = socket(server);
io.on('connection', socket => {
console.log('made the connection')
socket.on('chat',data => {
io.sockets.emit('chat',data)
});
socket.on('typing',data => {
socket.broadcast.emit('typing',data);
});
})
create another file and
var socket = io.connect('http://localhost:8080')
// Elenment
var message = document.getElementById('message');
handle = document.getElementById('handle');
btn = document.getElementById('send');
output = document.getElementById('output');
feedback = document.getElementById('feedback');
// Emit Events
btn.addEventListener('click', () => {
socket.emit('chat', {
message: message.value,
handle: handle.value
})
})
message.addEventListener('keypress', () => {
socket.emit('typing', handle.value)
})
socket.on('chat',data => {
feedback.innerHTML = '';
output.innerHTML += '<p><strong>' + data.handle +': </strong>' +
data.message + '</p>'
})
socket.on('typing', data => {
feedback.innerHTML = '<p><emp>' + data + ' is typing a message... </emp></p>'
})
details are given here node socket chat app
Ok, figured it out. Here's how it works using express and vue together :
First, setup socket.io in your express server js file :
const express = require('express')
const { Server } = require('socket.io')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST', 'REMOVE']
}
})
const PORT = process.env.PORT || 8080
io.on('connection', (socket) => {
console.log('New socket user')
socket.on('SEND_MESSAGE', data => {
console.log('received message in back')
io.emit('MESSAGE', data)
})
})
server.listen(PORT, () => { console.log(`Server started on port : ${PORT}`)})
As you can see we received from the client "SEND_MESSAGE" and we trigger MESSAGE from the server to forward the information to all the clients. The point I was missing is that we bind SEND_MESSAGE on the socked created from the connection but we emit from the io server.
Now you vue part :
import io from 'socket.io-client'
export default {
data() {
return {
messages: [],
inputMessage: null,
socket: io('http://localhost:8080')
}
},
mounted() {
this.socket.on('MESSAGE', data => {
this.messages.push(data)
})
},
methods: {
sendMessage() {
const message = {
senderID: this.myID,
message: this.inputMessage,
sendAt: new Date()
}
this.socket.emit('SEND_MESSAGE', message)
this.inputMessage = null
},
},
}
Hello i am trying to emit command using SOCKET to user when setting gets changed through some API..
but I dont know how can i get socket or tell socket to emit the message to user..
Please Help
this is my code
//Socket INIT
class Socket{
constructor(){
//Init variables
}
start(){
//Start socket
this.io.use((socket, next) => this.auth.authDevice(socket, next));
this.io.on('connection',(socket) => this.conn.handleConn(socket));
}
}
//Socket Connection
let socketStack = [];
class Connection{
handleConn(socket){
// store client
socketStack[socket.userid] = socket
}
pushCmd(userid, command){
//cheeck if userid exists in >>socketStack<< and emit
}
}
//Command Emit
class Command {
constructor(id) {
this.userid = id.userid
//socket - Connection class
this.socketConn = new SocketHandler()
}
static push(userid, command) {
//i want to sent it to current socket context. this has empty socketStack..
this.socketConn.pushCmd(userid, command);
}
}
let socket = new Socket();
socket.start() //connection started, all clients connect to //this socket .. I WANT API to use this socket to emit something that //API sends....
You have to make socket to 'listen' on server. For example, I'm using express with node.js, and this is the way I run socket.io:
var app = express();
var server = require('http').createServer(app);
var io = socketio.listen(server);
io.on('connect', function (socket) {
socket.on('exampleCall', function () {
console.log("socket invoked!");
socket.emit("exampleEmit");
});
});
server.listen(process.env.PORT || 3000, process.env.IP || "0.0.0.0", function () {
var addr = server.address();
console.log("Server listening at", addr.address + ":" + addr.port);
});