Socket.io namespace connection confuse - websocket

All:
I am pretty new to socket.io, when I tried namespace, I wonder why both the default channel and specified channel get called like:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
console.log("Send chat page");
res.sendFile(__dirname+'/index.html');
});
io.on('connection', function(socket){
console.log("Connected");
});
var chat = io.of("/chat");
chat.on('connection', function(socket){
console.log("Connected chat");
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
And the client code is like:
var socket = io("http://localhost:3000/chat");
When I run it, the console print out both "Connected" and "Connected chat"
I wonder why it works like this and how to only connect to chat channel?
Thanks

Related

Can't send a message from server to client with socket.io

I'm new to socket.io and was trying to send a message from server to client while following the instructions of basic emit on https://socket.io/docs/v4/emitting-events/. I expected when I connected to the socket, I would have the word 'world' printed on the console but I failed without knowing why. Did I do something wrong?
Server
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
io.emit('welcome', 'world');
});
http.listen(port, () => {
console.log(`Socket.IO server running at http://localhost:${port}/`);
});
Client
var socket = io();
socket.on('welcome', (arg) => {
console.log(arg);
}
After io.on('connection') You have to receive message from client using
socket.on('welcome',(data) {
//from there emit to client receive message
}) ;

socket.io client not able to connect and receive messages emit by server

I am emitting messages from socket.io server running on port 8001
but my socket.io client not able to connect and receive these messages
my index.html (client):
<script src="https://cdn.socket.io/socket.io-4.0.0.js"></script>
<script>
//var socket = io();
//var socket = io.connect('http://localhost:8001');
var socket = io('http://localhost:8001', { transports : ['websocket'] });
socket.on('connect', function(){
console.log("connected");
socket.on("message", data => {
console.log(data);
});
});
</script>
My nodejs server code:
const app = require("express")();
const server = require("http").createServer(app);
const io = require("socket.io")(server, {
cors: {
origin: '*',
}
});
io.on("connection", () => {
console.log("Connected!");
});
var redis = require('redis');
//var url = "redis://:#localhost:6379";
//var redis = require('redis-url').connect();
//var client = redis.createClient(url);
var client = redis.createClient();
//var client = redis.createClient();
client.on("error", function(error) {
console.error(error);
});
client.subscribe('notification');
client.on('message', function(channel, msg) {
console.log("Message received: "+msg);
io.sockets.emit(msg);
});
console.log('starting server on 8001...');
server.listen(8001);
My node js server console logs:
starting server on 8001...
Message received: from laravel
io.sockets.send(msg);
this worked for me. also make sure you are using the same version of socket.io on both client and server

Websocket between two computers on same LAN network

Is it possible to open a websocket between two computers that are either on the same WAN network or connected via an ethernet cable (LAN)? If it is, can someone provide with some readings I can do to learn about this?
EDIT: added my server code
'use strict';
var express = require('express'); //web server
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server); //web socket server
// ===============================Serial port setup========================
var serialport = require('serialport');
var SerialPort = serialport.SerialPort;
var parsers = serialport.parsers;
var openSocket = false;
var port = new SerialPort("/dev/ttyACM0", {
baudrate: 9600,
parser: parsers.readline('\r\n')
});
// ===============================Server Setup===========================
const netPort = 8080;
server.listen(netPort); //start the webserver on port 8080
app.use(express.static('public')); //tell the server that ./public/ contains
the static webpages
console.log("listening on port: localhost:" + netPort);
// ==============================Sending data======================
io.sockets.on('connection', function (socket) {
socket.emit('pi', { status: 'opened' });
console.log('Socket is open'); // log to console, once serial connection is established
openSocket = true;
});
port.on('data', function(data) {
if (openSocket) {
socket.emit('pi', {value: data}); //send data
}
});

Can't use Express to send data back to client more than once

In my app, I send a post request to the server with data containing a CSV file:
$.ajax({
type:"POST",
contentType: "application/json",
url:"/",
data: JSON.stringify({fileData:My_CSV_FILE}),
success: function(csvJson) {
console.log('in the done block!');
//can use csvJson in this handler
});
});
Note: I'm posting to the home route, and I am able to get a response with the data converted from the server. The problem is that whether I run on localhost or Heroku, I am only able to trigger the POST request once, then I have to restart the server (even if I refresh the page). So I know the issue is with my route somewhere:
UPDATED TO INCLUDE FULL SERVER FILE:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
var converter = new Converter({});
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.json(result);
}else {
res.json({error: 'Could not convert'});
}
})
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});
I'm using Express 4. Again, everything works, but only once. When I run Heroku logs, or check the console on localhost I get:
Error: Can't set headers after they are sent.
But I don't understand how I'm re-setting them.
If wanting to run on localhost, here is a link to the projects github: https://github.com/qctimes/calendar_export
You should move the converter instantiation to be done inside the app.post callback method. This way it will instantiate a new object at every request.
This is is how your code should be:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
var converter = new Converter({}); // instantiation is done here
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.send(result);
}else {
res.send({error: 'Could not convert'});
}
});
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});

Difference between io.on and socket.on in Socket.io?

I am confused on what the 'socket' parameter is that is passed with the function (In 'The enigma' section). Then the parameter gets used 'socket.on'. What is the difference between io.on and socket.on?
The following code is slightly adapted from the Socket.io chat application example.
Variables
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app)
var io = require('socket.io').listen(server);
The enigma
io.on('connection', function (socket) {
console.log('user connected');
socket.on('message', function(msg) {
console.log('message: ' + msg);
io.emit('message', msg);
})
});
Start server
server.listen(3000, function() {
console.log('server is running');
});
index.jade
body
script(src="/socket.io/socket.io.js")
form(method='post', action="/")
input(type='text', id='user', autocomplete='off')
input(type='submit', onClick="myFunc()")
strong messages:
p(id="messages")
script.
var socket = io();
socket.on('message', function(msg) {
console.log('client: ' + msg);
});
function myFunc() {
var text = document.getElementById('user');
socket.emit('message', text.value);
text.value = '';
};
In your code example, io is a Socket.IO server instance attached to an instance of http.Server listening for incoming events.
The socket argument of the connection event listener callback function is an object that represents an incoming socket connection from a client.
Both of them can listen for events with the on method.
It might help you visually understand how the two are separate if you re-imagine your code sample like this:
var connectionEvent = function(socket) {
console.log('user connected');
socket.on('message', function(msg) {
console.log('message: ' + msg);
io.emit('message', msg);
});
};
io.on('connection', connectionEvent);

Resources