Implement a socket connection in my apollo graphQL express server - javascript

I'm running an express based apollo graphQL server using apollo-server-express.
import express from 'express'
import cors from 'cors'
import server from './graphql/schema'
app.use(cors())
server.applyMiddleware({ app, path: '/graphql' })
app.listen(port, async () => {
if (process.env.NODE_ENV !== 'production') {
console.log('Listening on port ' + port)
}
})
export default app
Now I need to connect to some other applications from my client. Therefore he provides me with HL7 data. He told me to 'use a socket to get the HL7 data', which my application can use.
I just don't have a clue how to implement a socket connection at all.
Doing some researches brought me to libraries like socket.io, which should be used like this (for express):
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => { /* … */ });
server.listen(3000)
I don't understand how to implement the io in my existing code shown above.
I never used or implemented a socket connection at all, so I have very big understanding problems with that. Maybe the socket.io library is not the correct thing for my needs.

I do not have any knowlege about HL7 data, I think your another app has been writen by Java.
But, if you want to implement a socket.io server with apollo-server-express, just follow socket.io official document and attach a http server to express app and socket.io, then start your http server.
import express from 'express'
import cors from 'cors'
import GraphQLServer from './graphql/schema'
import socketIO from 'socket.io'
import http from 'http'
let app = express() // You missed this line ?
let httpServer = http.Server()
let io = socketIO(httpServer)
app.use(cors())
GraphQLServer.applyMiddleware({ app, path: '/graphql' })
httpServer.listen(port, async () => { // I don't see your `port`
if (process.env.NODE_ENV !== 'production') {
console.log('Listening on port ' + port)
}
})
io.on('connection', (socket) => {
console.log('A client connected', socket.id)
});
export default app

Related

How should I use proxy in a web app made with node.js and vanilla javascript?

I have a web app made in node.js and vanilla javascript. I wanna replace "http://localhost:4000/api/word" with "api/word" in the fetch api so that it works when the app's deployed on Heroku. I solved the issue by adding "proxy" : "http://localhost:4000" in package.json file when I used React for other apps but I don't know how to deal with the issue when I'm not using React.
server.js
const express = require("express");
const app = express();
const cors = require("cors");
const fs = require("fs");
const port = process.env.PORT || 4000;
app.use(express.json());
app.use(cors());
app.get("http://localhost:4000/api/word", function (req, res) {
fs.readFile("./wordlist.txt", (err, data) => {
if (err) throw err;
let wordList = data.toString().split("\n");
res.send(wordList);
});
});
main.js
function getWord() {
fetch("/api/word")
.then((res) => res.json())
.then((res) => {
...do something...
})
.catch((err) => console.log(err));
}
I tried the React way but it sends the get request to localhost:5500 which is the client side port.
Since your client and server are listening on different ports, I'm assuming your server isn't serving the client and that it has its own server. If the client doesn't need its own separate server, you can serve it from your express app by putting it in a directory and using express.static. Assuming you put the frontend code in a directory called public next to your server code, that would look like this:
app.use(express.json());
app.use(cors());
app.use(express.static(path.resolve(__dirname, 'public')));
If you do need to have a separate server for the client, there are modules just for this problem. http-proxy is a very popular one. I provided examples of how to use it here that could be easily adapted for any Node server, but there are many more in the docs.
Also just a sidenote, app.get("http://localhost:4000/api/word", function (req, res) should be app.get('/api/word' ...: your routes shouldn't define the scheme, host, and port.

How to connect to a nodejs socket server?

I am new to node JS and I am trying to create a real time application that consists of a node JS server with socket.io and a unity application that can connect to it
I created the server with the sockets in the below code :
const express = require('express');
const http = require('http');
const app = express();
const port = process.env.PORT || 9000;
const server = http.Server(app);
const io = require('socket.io')(server);
io.on('connection',(socket) => {
console.log('A user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
app.get('/',(req,res) =>{
res.json({worked : 'worked'});
});
server.listen(port,() => console.log(`Listening on localhost ${port}`));
I can connect to the socket server via the nodejs client files using socket.io-client
<script>
const socket = io('http://localhost:9000');
socket.on('message',(message) => console.log(message));
</script>
But the problem is whenever I try to connect from a different client I don't receive anything in the console.
I tried to use Smart Web Socket client to debug what's happening but whenever I connect (try to)
this happens
Any help would be much appreciated and thanks in advance
So if anyone stumbles in this thread I was able to fix the problem by installing the latest version of socket.io (^3.1.0) and allowing the EIO3 connections

Cannot access Node.JS Backend via localhost

I'm working to setup a Node backend to feed data and communicate with ReactJS for my frontend. Ultimately I am developing new company software to replace our current Transportation System.
I utilize Amazon EC2 Ubuntu 16.04 - for my own reasons for my business - and I simply cannot get my ReactJS frontend with Socket.IO to communicate with my nodeJS backend with Socket.IO on http://localhost:4000/.
This is my App.js in my react frontend
import React, { Component } from 'react';
import logo from './logo.svg';
import ioClient from 'socket.io-client';
import './App.css';
var socket;
class App extends Component {
constructor() {
super();
this.state = {
endpoint: 'http://localhost:4000/'
};
socket = ioClient(this.state.endpoint);
}
This is my nodeJS index for the backend
const mysql = require('mysql');
const http = require('http');
const express = require('express');
const cors = require('cors');
const app = express();
const server = http.createServer(app);
const io = require('socket.io').listen(server);
//app.use(cors());
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
const sqlCon = mysql.createConnection({
host: 'localhost',
user: 'admin-user',
password: 'admin-pass',
database: 'sample'
});
sqlCon.connect( (err) => {
if (err) throw err;
console.log('Connected!');
});
io.on('connection', (socket) => {
console.log('user connected');
});
server.listen(4000, "localhost", () => {
console.log('Node Server Running on 4000')
});
I can get it to communicate via my actual Public IP address, but not via localhost. I really don't want to expose my backend on my public IP address to communicate with it for all users. This has probably been asked before, but I honestly can't find a clear answer for it anywhere and I've been looking for 3 days now. Node has no problem executing, and like I said if I create the socket.io connection from the public IP, I can get it to communicate and as far as I can tell node has no problem running the rest of the script as it connects to mariaDB no problem.

production calling api from localhost

I have deployed my application (created with npm run build) to heroku. However, the api calls done on heroku production are from my localhost. How do I change this? Could anyone please advice?
api_axios.js
const axios = require('axios')
export default () => {
return axios.create({
baseURL: 'https://myapp.herokuapp.com/api/' || 'http://localhost:1991/api/'
})
}
server.js
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const port = process.env.PORT || 1991
// express app
const app = express()
// middleware
app.use(cors())
// routes
const metrics = require('./routes/api/metrics')
app.use('/api/metrics', metrics)
// handle production
if(process.env.NODE_ENV === 'production'){
// static folder
app.use(express.static(__dirname + '/public/'))
// handle spa
app.get(/.*/, (req, res) => res.sendFile(__dirname + '/public/index.html'))
}
// run server
const server = app.listen(port, ()=>{
console.log(`server running on port ${port}`)
})
Just like you check process.env.NODE_ENV in your server, you should also check environment when you compile your JavaScript.
You can use environment variables (via process.env as above), configuration files (such as require('./config.json'), or any other method you like. At the end of the day though, you shouldn't hardcode your API URL.

Nuxt JS with WebSockets

I have a Nuxt App, with one service which needs to be delivered over WebSockets. The Nuxt App Server provides an api service using express.
I have an /api folder in which there are various *.js files, and these are routed to successfully. ie...
const express = require('express');
const app = express();
app.get('/whatever1',(req, res) => console.log('req.url',req.url))
works OK.
However the following, in the same file, will never be reached....
const express = require('express');
const app = express();
const expressWs = require('express-ws')(app);
app.ws('/whatever2',(ws,req) => {
console.log('req.url',req.url);
})
Where am I going wrong ?
You're attempting to connect the client to an endpoint on the server where no such endpoint exists. In your client's output, you're receiving an error of:
VM1295:1 WebSocket connection to 'ws://localhost:3000/api/whatever2' failed: Connection closed before receiving a handshake response
because you haven't defined a route of /api/whatever2. Your code above routes to:
ws://localhost:3000/whatever2
instead of ws://localhost:3000/api/whatever2
EDIT:
Here's test code that worked for me:
const express = require('express');
var app = express();
const expressWS = require('express-ws')(app);
expressWS.getWss().on('connection', function (ws) {
console.log('connection open');
});
app.ws('/whatever', (ws, res) => {
console.log('socket', ws);
});
app.listen(3000, () => console.log('listening on 3000...'));

Categories