Unable to connect to socket.io using express server - javascript

I'm trying to create WebSocket using the following code.
const express = require('express')
const app = express()
const http = require('http')
const server = new http.createServer(app)
const io = require('socket.io')(server)
const CONFIG = {
host: 'localhost',
port: 4444
}
io.on('connection', function (socket) {
const sid = socket.id
console.log('connection socket id:', sid)
for (const msg of ['disconnect', 'disconnecting', 'error']) {
socket.on(msg, data => {
console.log(`* ${msg}:`, data)
})
}
socket.on('join', data => {
console.console.log("data", data)
})
socket.on('signal', data => {
console.log('signal', data)
})
})
server.listen({
host: CONFIG.host,
port: CONFIG.port,
}, info => {
console.info(`Running on`, server.address())
})
When I try to test this using https://www.websocket.org/echo.html I'm receiving an undefined error.
I have given ws://127.0.0.1:4444 in the location field but when I try to connect I'm getting the following error in the Log:
ERROR: undefined
and in the message Connection closed before receiving a handshake response
What is wrong here how I can make this working?

Your server seems good, you should implement the client yourself.
Socket.IO server and client example from the documentation.
Server:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
socket.on('message', (msg) => {
console.log('message: ' + msg);
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
Client (index.html):
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$(function () {
var socket = io();
socket.emit('message', 'Test message.');
});
</script>

Related

Is there a way to host a Socket.Js server on Github?

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/chat.html');
});
server.listen(8000, () => {
console.log('listening on *:8000');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
});
});
io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' }); // This will emit the event to all connected sockets
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});
Currently it's localhost, and I have to run node index.js everytime I want to start it. But is there a way I can host it on GitHub so it always stays on?
Short answer: No.
GitHub hosts git repositories containing code, but doesn't run code. GitHub pages can serve static sites, but cannot run server side code, which include node.js and express. If you want to host something like this for free, I suggest looking into Heroku.

unable to send post request using socket.io

here i am sending data from socket client to socket server and after receiving the request it has to send to node api
**the issue is im getting null ** on calling the socket server
below is my code
Socket Client
socket.connect();
socket.emit("posreq",JSON.stringify({ "title": "data"}));
Socket Server
var http = require('http'),
io = require('socket.io'), // for npm, otherwise use require('./path/to/socket.io')
request = require('request'),
cors = require('cors'),
server = http.createServer(function (req, res) {
// your normal server code
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end('Hello world');
});
server.listen(4000);
// socket.io
var socket = io.listen(server);
socket.on('connection', function (client) {
// new client is here!
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
Node api
const express = require('express')
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express()
const port = 3000
let books = [{
"title": "Eloquent JavaScript, Second Edition",
}];
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/book', (req, res) => {
const book = req.body;
// output the book to the console for debugging
console.log(book);
// books.push(book);
res.json('Book is added to the database');
});
I tried but unable to understand the issue
Note : How can i convert the Socket server to express js code
As far I understand you are willing to use express instead of HTTP and that will solve your problem. And in the below code, I have used express as well as HTTP. Try code below
const express=require("express")
const app=express()
const server=require("http").createServer(app)
const socket=require("socket.io")(server)
server.listen(4000,()=>console.log(`Listening to port 4000`))
socket.on('connection', function (client) {
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
May be you need few modification,
Request is depricated so better to use axios or other alternative.
const express = require("express")
const bodyParser = require("body-parser")
const axios = require('axios')
const app = express()
const httpServer = require("http").createServer(app)
const socket = require("socket.io")(server)
app.use(bodyParser.json({ limit: '16mb' }));
app.use(bodyParser.urlencoded({ limit: '16mb', extended: true, parameterLimit: 50000 }));
app.get('/', (req,res)=> res.send("Hello world"));
socket.on('connection', function (socket) {
socket.on('posreq', async (body) => {
try {
const { data } = await axios.post("http://localhost:3000/book", { body })
socket.send("post req called", data);
} catch (error) {
socket.send("post req error", error);
}
});
socket.on('disconnect', function () {
console.log('connection closed');
});
});
httpServer.listen(3000, () => console.log(`Spinning 3000`))

jaeger endpoint isnt recieving data using jaeger Node.js client

Was trying to connect to jaeger using HTTP request using nodejs but the spans are not reaching the jaeger endpoint. please help with this code snippet.,
var initTracer = require('jaeger-client').initTracer;
var config = {
'serviceName': 'servicename1',
'reporter': {
'collectorEndpoint': 'http://jaeger-collector:14268/api/traces',
}
};
var options = {
tags: {
'servicename1': '1.0'
}
};
var tracer = initTracer(config, options);
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
app.get('/', (req, res) => {
const span = tracer.startSpan('http_request');
res.send('Hello Jaeger');
span.log({'event': 'request_end'});
span.finish();
});
app.get('/', function(req, res) {
res.send("Hello World!");
});
server.listen(3000);
console.log('Express server started on port %s', server.address().port);
Any help would be much appreciated!
Got it! We need to enable sampling strategy to reach the collector endpoint.
var initTracer = require('jaeger-client').initTracer;
var config = {
'serviceName': 'Jaeger_Service',
'reporter': {
'collectorEndpoint': 'http://jaeger-collector:14268/api/traces',
},
'sampler': {
'type': 'const',
'param' : 0.1
}
};
var options = {
'logger': {
'info': function logInfo(msg) {
console.log('INFO ', msg)
},
'error': function logError(msg) {
console.log('ERROR', msg)
}
}
};
var tracer = initTracer(config, options);
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
app.get('/', (req, res) => {
const span = tracer.startSpan('http_request');
res.send('Hello Jaeger');
span.log({'event': 'request_end'});
span.finish();
});
server.listen(8000);
console.log('Express server started on port %s', server.address().port);

Showing MQTT response on a node server API

I'm trying to output the response I receive from MQTT to a node serve setup using express.
There will be a json string message received from the mqtt service at every second.
The response would be output on /main API, which I would call from a Ionic 4 mobile app I'm working on.
However, now I can't display the data on the server itself just to check, I haven't thought of how I would constantly update the data as well on the server. The page doesn't refresh it just keeps loading.
const mqtt = require('mqtt')
const express = require('express')
const PORT = 8000
const app = express()
var client = mqtt.connect("mqtt://bac.com")
client.on('connect', () => {
console.log("Connected")
client.subscribe('/test')
})
app.get("/", (req, res) => {
res.send("ROOT");
});
app.get("/main", (req, res) => {
client.on('message', (topic, message) => {
res.send(message)
})
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
You would need to store your data somehow on the server side for your approach to work.
Implement some kind of storage service that stores the messages. Your client will need to respond to the queue messages and push these to storage, your api action will retrieve them from the storage, not from the queue.
const mqtt = require('mqtt');
const express = require('express');
const PORT = 8000;
const app = express();
const storageService = require("SOME KIND OF STORAGE SERVICE");
var client = mqtt.connect("mqtt://bac.com");
client.on('connect', () => {
console.log("Connected")
client.subscribe('/test')
});
client.on('message', (topic, message) => {
storageService.save(topic, message); //or this has to provide storage and enterpretation of the data comming in
});
app.get("/", (req, res) => {
res.send("ROOT");
});
app.get("/main", (req, res) => {
res.send(storageService.getAll());
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
You could also revisit the entire implementation, and push messages to the frontend via a socket or some other kind of persistant connection.
I have found a workaround from a similar question here. On the server side it will send data on message received. On the client side, it is an ajax call for every second to retrieve the data on the server side.
As described in the link, it really is a bad pattern. However, this would be suitable for those who have constraints to making changes to the MQTT service.
// Server.js
const mqtt = require('mqtt')
const express = require('express')
const PORT = 8000
const app = express()
var client = mqtt.connect("mqtt://bac.com")
var mqttMessage
client.on('connect', () => {
console.log("Connected")
client.subscribe('/test')
})
client.on('message', (topic, message) => {
console.log('Topic: ' + topic + '\nMessage: ' + message)
mqttMessage = message
})
app.get("/", (req, res) => {
res.sendFile("__dirname + "/index.html");
});
app.get("/main", (req, res) => {
if(mqttMessage)
res.send(mqttMessage);
else
res.status(404).send();
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
and on the index.html page:
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(document).ready(
function () {
setInterval(function () {
$.get('/main', function (res) {
$('#data').text(res);
});
}, 1000);
}
);
</script>
<p id="data"></p>
</body>

how to set max. of clients of socket io?

to my server are just two clients allowed to connect with. How to set the max of clients on two clients of socket.io?
this is how my server.js looks like:
var path = require('path');
var express = require('express'),
app = express(),
http = require('http'),
socketIo = require('socket.io');
var server = http.createServer(app);
var io = socketIo.listen(server);
server.listen(9000);
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + 'index.html'));
});
app.use(express.static(__dirname + '/'));
io.on('connection', function (socket) {
socket.on('data', function (data) {
socket.broadcast.emit('data', data)
});
socket.on('disconnect', function () {
console.log("disconnect")
});
});
This is untested, but you should be able to check number of users on connection and change it on connect/disconnect.
Here is an example:
const connectedUsers = 0;
const maxUsers = 2;
io.on('connection', function (socket) {
if(connectedUsers + 1 > maxUsers){ // check if the new connection will exceed the max connections allowed
socket.disconnect(); // if so, disconnect the user and exit https://stackoverflow.com/a/5560187/11518920
return;
}
connectedUsers++; // otherwise + 1 to the connectedUsers
socket.on('data', function (data) {
socket.broadcast.emit('data', data)
});
socket.on('disconnect', function () {
connecteUsers--; // on a disconnected decrease the connectedUsers count
console.log("disconnect")
});
});

Categories