Reputation: 112
I have gone through few stackoverflow question. Still unable to under where my concept is wrong. Background: nodejs app I'm learning works as I want it to be. It can make GET or POST request from CURL, fill in data to mongodb. My app is also listening on socket. When ws.on('message')... I would like to call same Web API route internally to my app. But that doesn't seems to invoke. "Final goal is to get the socket message and GET/POST to my internal /api route. Below I have my app code:
server.js
var express = require('express');
var http = ('http'); const mongoose = ('mongoose');
const WebSocket = ('ws');
var routes = require('./routes/index'); var api = ('./routes/api');
var app = express();
app.use('/', routes);
app.use('/api', api);
mongoose.Promise = global.Promise;
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
} );
// connect to database
mongoose.connect('mongodb://localhost/mdb')
.then(() => console.log('db connection successful'))
.catch((err) => console.error(err));
http.createServer(app).listen(8080);
//Create a websocket to receive notification
const ws = new WebSocket('ws://localhost:8031');
ws.on('open', function open() {
console.log('ws connection successful');
});
//get or post message to webapi /api/v1 path
ws.on('message', function incoming(data) {
//this route seems never been called
app.get('api/v1', function (res) {
res.send('hello');
});
console.log('Socket message: ' + data);
});
module.exports = app;
api.js
var express = require('express');
var router = express.Router();
const mogoose = require('mongoose');
const Data = require('../models/dbModel');
const TempData = require('../models/TempModel');
/* GET data for listing. */
router.get('/v1/', function (req, res, next) {
Data.find(function (err, data)
{
if (err) return next(err);
res.json(data);
});
});
package.json
"dependencies": {
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"debug": "~2.0.0",
"express": "^4.9.8",
"express-controller": "^0.3.2",
"jade": "~1.6.0",
"mongodb": "^3.0.1",
"mongoose": "^5.0.2",
"morgan": "~1.3.0",
"request": "^2.83.0",
"serve-favicon": "~2.1.3",
"stylus": "0.42.3",
"ws": "^4.0.0"
},
"main": "server.js"
Please fill in your comments and hints. Have been stuck with this issue for 1.5 days.
Upvotes: 1
Views: 4761
Reputation: 61
I was able to solve this easily by making socket.io available on all routes by default: passing it as a default middleware
import socketIo from 'socket.io';
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: "http://frontendUrL" }
});
app.use(bodyParser.json());
app.use((req, res, next) => {
req.io = io;
return next();
});
Call socket io from any route using
req.io.sockets.emit('broadcast', {message: 'You have a new Visitor', url
: url});
Upvotes: 0
Reputation: 10111
Why you want call route, just perform the same operation on socket event
// api.js
var handler = function (cb) {
// Do some stuff
Data.find(cb);
}
router.get('/v1/', (req, res, next) => {
handler(function (err, data) {
if (err) return next(err);
res.json(data);
});
});
module.exports = {
handler
};
// server.js
var appJs = require('./app');
ws.on('message', function incoming(data) {
/* No need to call route perform whatever operation route is doing */
appJs.handler(function (err, data) {
console.log('Socket message: ' + data);
// Do some stuff
});
});
Upvotes: 0
Reputation: 4328
You can use supertest
and make calls to your own API.
const app = require('./server.js');
const request = require('supertest');
request(app)
.get('/api/v1')
.expect(200)
.end(function(err, res) {
if (err) throw err;
else console.log(res);
});
Ref: https://github.com/visionmedia/supertest
You can also create a function like this:
router.get('/v1/', function (req, res, next) {
exports.findData(function(results){
res.json(results);
})
});
exports.findData = function(callback) {
Data.find(function (err, data) {
if (err) return next(err);
callback(data);
});
}
And in your WebSockets:
const findData = require('./router').findData;
// ...
ws.on('message', function incoming(data) {
findData(function () {
console.log('Socket message: ' + data);
})
});
Upvotes: 1
Reputation: 2849
From ws's docs
const WebSocket = require('ws');
const ws = new WebSocket('ws://www.host.com/path');
ws.on('open', function open() {
ws.send('something');
});
ws.on('message', function incoming(data) {
console.log(data);
});
It seems like a config issue, see: const ws = new WebSocket('ws://www.host.com/path');
Upvotes: 0