I have a server that receives webhooks, sends them to a client via websockets. Since I am listening for both on the same port, if webhooks work, websockets dont and vice versa. How would I go about solving this. Here is the code for the server
const express = require('express');
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser.json())
app.post("/", (req, res) => {
console.log(req.body);
res.status(200);
res.send(req.body);
echo(req.body);
});
app.listen(3000, '0.0.0.0', () => console.log('Server is live at 3000'));
const WebSocket = require('ws');
const SocketServer = require('ws').Server;
const server = express().listen(3000);
const wss = new SocketServer({server});
wss.on('connection', (ws) =>{
console.log("Connected");
ws.send("Connected To Server")
ws.on('close', () => console.log("Disconnected"));
});
function echo(webhook){
wss.clients.forEach(function each(client){
client.send(webhook);
});
}
How would I run webhook listener and websocket sender/listener on same port
Can I run both of them on different ports on the same url
a) If yes what would be the url for both ports, if my website is www.example.com
If all that is not possible, what would be a good alternative
Related
Scenario: Creating a Node API (GET) calling that API in socket.io Node server and calling this socket server in angular client.
What i have done: Created a node API for get request and post and created a socket server I tried to consume the app.
Issues: 1. I tried to consume the API but was unable to get the data in the socket server and 2. If it works, also how can i get the socket data on button click in angular application?
Note: I'm running Node API on 3000 server and running socket server on 3001.
Below is my code
Node api code runnning on 3000 port:
const express = require('express')
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express()
const port = 3000
let books = [{
"isbn": "9781593275846",
"title": "Eloquent JavaScript, Second Edition",
"author": "Marijn Haverbeke",
"publish_date": "2014-12-14",
"publisher": "No Starch Press",
"numOfPages": 472,
}];
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.send('Book is added to the database');
});
app.get('/book', (req, res) => {
res.json(books);
});
app.listen(port, () => console.log(`Hello world app listening on port ${port}!`));
Socket .io server running on 3001
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
const apiUrl="http://localhost:3000/book"
io.on('connection', function (socket) {
socket.on('getBanners', function(data){
request.get(apiUrl,function (error, response, body){
console.log(body)
socket.emit('result', {res:JSON.parse(body)})
})
});
});
http.listen(3001, function(){
console.log('listening on *:3001');
});
Note: Node API server --> socketio server (not client)
I wouldn't recommend going by that design you have.
Unless there is a very specific/important reason to have the socket.io server on a different port than the HTTP server, I would recommend having your socket.io server upgraded from the HTTP server itself.
eg.
In bin/www:
const { initSocketIOServer } = require('../socket-server');
const port = normalizePort(process.env.PORT || '3001');
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
initSocketIOServer(server);
In socket.server.js
module.exports.initSocketServer = (server) => {
io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('client connected');
socket.on('getBanners', (event) => {
// handle getBanners event here
});
});
};
However, going by your example, if you really need to make a request to the HTTP server to fetch data, you might want to use the HTTP library:
socket.on('getBanners', (event) => {
http.get({
hostname: 'localhost',
port: 3000,
path: '/book',
agent: false // Create a new agent just for this one request
}, (res) => {
// Do stuff with response, eg.
const socketResponse = processBooks(book);
socket.emit('result', socketResponse);
});
});
You can use any node package for requests like request https://github.com/request/request
here
I've been trying to create an app that uses telegram-bot, express server and react app. Therefore, I need to create a POST request from telegram-bot to express, while express sends POST data to a websocket connection:
const express = require("express");
const app = express();
const expressWs = require("express-ws")(app);
// handles bot request
app.post("/request", (req, res) => {
playlist.push(req.body.url);
res.status(200).send({ message: "video is added to playlist" });
});
// after handling requst data must go here and send ws message to client side
app.ws("/echo", (ws, req) => {
ws.on("message", msg => {
ws.send(`msg is = ${msg}`);
});
});
Am I making it right, and if so, how to call ws.send from after handling request at app.post route?
From the understanding I have from your question, here is an updated version of your code that does exactly what you want.
I replaced the express-ws package with ws since that would be sufficient for your use case.
The express server runs on port 8080 while the websocket server runs on port 8081 since are different protocols and would not run on the same port (You can make it work but I do not recommend it See this question
const express = require("express");
const Websocket = require('ws');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const wss = new Websocket.Server({ port: 8081 });
wss.on('connection', (ws) => {
console.log('One client connected');
ws.on("message", msg => {
ws.send(`msg is = ${msg}`);
});
})
// handles bot request
app.post("/request", (req, res) => {
// Broadcast URL to connected ws clients
wss.clients.forEach((client) => {
// Check that connect are open and still alive to avoid socket error
if (client.readyState === Websocket.OPEN) {
client.send(url);
}
});
res.status(200).send({ message: "video is added to playlist" });
});
app.listen(8080, () => {
console.log('Express listening on 8080');
console.log('Websocket on 8081');
});
Tested via curl with curl -d 'url=https://example.com/examplesong' localhost:8080/request I had a client connected to ws://localhost:8081 and everything looks good.
I am using socket.io both (server API and client API) on Node.js as client and server. This is possible as specified in the docs). I am not using any particular frameworks except Express and followed the official guide for using socket.io with it.
On the server side I have:
const express = require("express");
const app = express();
const http = require("http");
server = http.Server(app);
const io = require("socket.io")(server) //server listens on "http://localhost:3001
io.on("connection", socket => {
console.log("server says: someone connected");
});
On the client side I have:
const io = require("socket.io-client")("http://localhost:3001");
io.on("connect", () => {
console.log("client says: connected");
});
Until here everything works fine... Now when adding namespaces nothing seem to work anylonger. I followed the official guide and ended up with the following:
On the server side I have:
const express = require("express");
const app = express();
const http = require("http");
server = http.Server(app);
const io = require("socket.io")(server) //server listens on "http://localhost:3001
const nsp = io.of('/my-namespace');
nsp.on("connection", socket => {
console.log("server says: someone connected");
});
On the client side I have:
const io = require("socket.io-client")("http://localhost:3001");
const socket = io('/my-namespace');
socket.on("connect", () => {
console.log("client says: connected");
});
But the after the introduction of namespaces nothing seems to work... What am I missing?!
Thanks I am completely lost
I have these code for a Chat App and it is only working in Local Server
I have already tried the following. Calling io() without any path arguments.
// Client Side Code
socket = io();
socket.connect({ query: `username=${props.username}` })
The above didnt work. The app runs but does not show other user's messages.
// Client Side Code
socket = io('http://myherokuapp:3001', { query:
`username=${props.username}` }).connect();
Neither did the above code work. The app crashed on this one.
Here is my actual source code:
// Server Side Code
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 3001;
const app = express();
const http = require("http");
const cors = require("cors");
const io = require("socket.io");
const server = http.createServer(app);
const socketIo = io(server);
app.use(cors());
app.get('/messages', (req, res) => {
res.sendFile(path.resolve('./public/index.html'));
});
socketIo.on('connection', socket => {
const username = socket.handshake.query.username;
console.log(`${username} connected`);
socket.on('client:message', data => {
console.log(`${data.username}: ${data.message}`);
socket.broadcast.emit('server:message', data);
});
socket.on('disconnect', () => {
console.log(`${username} disconnected`);
});
});
server.listen(PORT, () => {
console.log(`🌎 ==> API server now on port ${PORT}!`);
});
// Client Side Code
socket = io('http://localhost:3001', { query:
`username=${props.username}` }).connect();
socket.on('server:message', message => {
addMessage(message);
});
socket.emit('client:message', messageObject);
addMessage(messageObject);
I expect the chat app to be working same as it does in localhost.
I was following the second example here:
https://github.com/socketio/socket.io-client
and trying to connect to a website that uses websockets, using socket.io-client.js in node.
My code is as follows:
var socket = require('socket.io-client')('ws://ws.website.com/socket.io/?EIO=3&transport=websocket');
socket.on('connect', function() {
console.log("Successfully connected!");
});
Unfortunately, nothing gets logged.
I also tried:
var socket = require('socket.io-client')('http://website.com/');
socket.on('connect', function() {
console.log("Successfully connected!");
});
but nothing.
Please tell me what I'm doing wrong. Thank you!
Although the code posted above should work another way to connect to a socket.io server is to call the connect() method on the client.
Socket.io Client
const io = require('socket.io-client');
const socket = io.connect('http://website.com');
socket.on('connect', () => {
console.log('Successfully connected!');
});
Socket.io Server w/ Express
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const port = process.env.PORT || 1337;
server.listen(port, () => {
console.log(`Listening on ${port}`);
});
io.on('connection', (socket) => {
// add handlers for socket events
});
Edit
Added Socket.io server code example.