I'm having the following logic (all servers are in Node.js) :
1- Client makes an API call to Server A's "api/request" endpoint.
2- Server A "request" endpoint receives the request, and just passes the original request to Server B with a socket.io emit event.
3- Server B socket.io on event receives the request, handles it, and sends back the response in a new socket.io emit event.
4- Server A socket.io on event receives the response, and is supposed to return the response to the Client who originally made the request.
The issue is that since in Server A I'm passing the request with socket.io emit event, I'm loosing the option to wait for an answer from Server B to return to Client anything. I would like Client to receive the response from Server B, as a response from its original call to Server A.
Any idea on how to achieve this?
In order to do it, you need to create an index. js file and install socket.io and express. You can use the following command: touch index. js && npm install express socket.io && npm install --save-dev nodemon .
The bidirectional channel between the Socket.IO server (Node. js) and the Socket.IO client (browser, Node. js, or another programming language) is established with a WebSocket connection whenever possible, and will use HTTP long-polling as fallback.
I found a way. Since you can only have one io.on('connection', function (socket) {})
in your code, I had to find a way around it.
The issue was that if you place io.on('connection', function (socket) {})
within your router.post('/', async (req, res) => {})
, it will only be triggered when you call your endpoint. In my case, I had some sockets events that I wanted to be called at anytime, not only when the endpoint is called. So I had to place the io.on('connection', function (socket) {})
outside of my router.post('/', async (req, res) => {})
. Thus I couldn't use var io = req.app.get('socketio');
inside the router. Here is what I have done instead in Server A code:
index.js:
const cors = require('cors');
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const taskRequest = require('./routes/taskRequest')(io);
app.use(cors())
app.use(express.json());
app.use('/api/taskRequest', taskRequest);
server.listen(4002);
routes/taskRequest.js
const express = require('express');
const router = express.Router();
module.exports = function(io) {
//we define the variables
var sendResponse = function () {};
io.sockets.on("connection",function(socket){
// Everytime a client logs in, display a connected message
console.log("Server-Client Connected!");
socket.on('connected', function(data) {
//listen to event at anytime (not only when endpoint is called)
//execute some code here
});
socket.on('taskResponse', data => {
//calling a function which is inside the router so we can send a res back
sendResponse(data);
})
});
router.post('/', async (req, res) => {
//pickedUser is one of the connected client
var pickedUser = "JZLpeA4pBECwbc5IAAAA";
io.to(pickedUser).emit('taskRequest', req.body);
sendResponse = function (data) {
return res.status(200).json({"text": "Success", "response": data.data});
}
});
return router;
};
Like this, Server A is only sending back to Client the response once it has received the response from Server B.
Solved!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With