GraphQL playground subscription fails with 400 error code.
WebSocket connection to 'ws://localhost:3000/graphql' failed: Error during WebSocket handshake: Unexpected response code: 400
I have an existing code based on express. I've integrated Apollo v2 this way:
const { ApolloServer, PubSub, gql } = require('apollo-server-express');
...
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers
});
server.applyMiddleware({ app });
...
app.listen(port, () =>
console.log(chalk.blue(`App listening on port ${port}!`)),
);
and then i start my existing app on port 3000 and can access the GraphQL playground on http://localhost:3000/graphql. All queries and mutations work as expected
Now I want to add subscriptions. Turns out I need to use an http server:
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
and then listen to it on another port:
httpServer.listen(3005, () => {
console.log(`Server ready at http://localhost:3005${server.graphqlPath}`);
console.log(`Subscriptions ready at ws://localhost:3005${server.subscriptionsPath}`);
});
So I have two servers running. My own on port 3000 and the subscriptions server on 3005. Is that the right way? Is it the only way?
There's no need to call both app.listen and httpServer.listen -- calling httpServer.listen will expose both your Express app and the subscription server.
Additional reading: Express.js - app.listen vs server.listen
Related
Could not connect to localhost:3000
17:02:53
Error: Unexpected server response: 404
Handshake Details
Request URL: http://localhost:3000/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 404 Not Found
My express server listen on 3000 port and socketio http on 443 port, i am able to connect socket by hosting this on ec2 instance and using ec2 ip with port number on postman socket connection ui, but on localhost connection always failed with above error on postman socket beta ui.
You need to call listen only once. If you pass your http/https server to express, app.listen() is enough. (except you want to listen on 2 different ports.. For testing, let's call it only once.)
For accessing it on localhost try setting it explicitly with the parameter hostname in app.listen().
Example:
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
// Let's only call listen once for testing purposes. If you call
// listen on the express app, your https server will automatically listen
// to the same configuration.
// httpsServer.listen(4000);
const port = 3000
const hostname = 'localhost'
// explicitly let the app listen on localhost. If hostname is not
// provided, it will take the first found ipv4 interface
app.listen(port, hostname, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on https://${hostname}:${port} 🛡️
################################################
`);
});
}
Now you should be able to connect your socket. If it still does not work try
to use http module instead of https for better isolating your problem.
Note that your server now only will be accessible using localhost and not over ip. Both may only be possible when running 2 server instances with different hostnames.
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
httpsServer.listen(443);
app.listen(config.port, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on port: ${config.port} 🛡️
################################################
`);
});
}
This is my app.ts file, I am using Ubuntu. so 443 port is not allowed, i changed this port to 4000, now the app listen on the 3000 and socket http server on 4000, but socketio not able to connect with socket url localhost:3000
I am new to node.js coding. I am learning to build a app I want to host on GCP App engine.
I have created a Node.js code which has hard requirement to listen to port 3000.
const dotenv = require('dotenv').config();
const express = require('express');
const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');
const { Console } = require('console');
// const PORT = process.env.PORT || 3000;
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello App Engine!');
});
On Yaml file I have specifically added ports to forward.
network:
forwarded_ports:
- 3000/tcp
unless I dont use 8080 port, app engine is failing with 502 Bad Gateway.
Is there a way I can use Port 3000 in App engine.
It works if I change the Port to 8080. But I want this to be at 3000.
I created firewall rules
enter image description here
Nope, you cannot change the default port in GAE.
The forwarded_ports is intended to open access to other services listening on other ports but always there should be something listening on the port 8080.
You can create a dummy service listening in port 8080 and possibly redirect to your app in port 3000. Something else to keep in mind is that when accessing the desired service in port 3000 or any other, this should be specified in the url like https://PROJECT_ID.REGION_ID.r.appspot.com:3000 or more general https://PROJECT_ID.REGION_ID.r.appspot.com:PORT
I want to make an Chat application with Socket.io and I've followed this tutorial: https://youtu.be/ZwFA3YMfkoc. I am using React and Node.js
Everything works fine while using it locally and even on different devices on my Network. However if I am hosting my Backend on Heroku it doesn't work.
The error Message is:
WebSocket connection to 'URL' failed: WebSocket is closed before the connection is established.
(URL is the URL of my Backend with the Port). I am using SSL.
I've already tried to enable session affinity but it already was enabled.
My backend code is: (atleast the code that I think is important to the Problem)
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(cors());
server.listen(PORT, () => console.log("Server started on " + PORT));
My frontend code is written in React and is:
var connectionOptions = {
"force new connection": true,
reconnectionAttempts: "Infinity",
timeout: 10000,
transports: ["websocket"],
};
const ENDPOINT = "URL";
socket = io(ENDPOINT, connectionOptions);
So I've fixed my Problem.
The URL on the client side had to be without the Port.
So for example:
const ENDPOINT = "https://web.site.com";
and not:
const ENDPOINT = "https://web.site.com:1337";
Call socket.connect() or just add autoconnect: true in options you are providing.
I'm trying to deploy my Node.JS app to Azure App Service. I followed this introduction: https://learn.microsoft.com/de-de/azure/app-service/app-service-web-get-started-nodejs.
Here is the code of my app:
var express = require('express'); // Web Framework
var app = express();
var sql = require('mssql'); // MS Sql Server client
const { request } = require('http');
// Connection string parameters.
var sqlConfig = {
user: 'username',
password: 'password',
server: 'serveraddress',
database: 'databasename'
}
// Start server and listen on http://localhost:80/
var server = app.listen(80, function () {
var host = server.address().address
var port = server.address().port
console.log("app listening at http://%s:%s", host, port)
});
app.get('/tags', function (req, res) {
sql.connect(sqlConfig, function() {
var request = new sql.Request();
request.query('select * from dbo.Tag', function(err, recordset) {
if(err) console.log(err);
res.end(JSON.stringify(recordset)); // Result in JSON format
});
});
})
The app runs locally without any problems. Simple testing in browser by typing localhost:80/tags returns all tags as json.
But after deployment to Azure this error occurs:
2020-06-25T17:11:58.055Z ERROR - Container wearxapplication_0_ed215082 for site wearapplication did not start within expected time limit. Elapsed time = 230.0801107 sec
2020-06-25T17:11:58.074Z ERROR - Container wearxapplication_0_ed215082 didn't respond to HTTP pings on port: 8080, failing site start. See container logs for debugging.
2020-06-25T17:11:58.088Z INFO - Stopping site wearxapplication because it failed during startup.
What its mean? How solve it?
Looking at the errors, I believe you are using App Service on Linux with Single container configuration. If so, do not explicitly listen on port 80 or any other (unless you are deploying via custom container where you would have control of the docker file). Behind the scene, app service on Linux deploys a container and expose an auto-detected port (docker expose). Your explicit listening port is unlikely to match that auto-detected port. Replace you server bootstrap code with below snippet to let the port get picked up from environment:
// Start server and listen on http://localhost:port/ for local
const port = process.env.PORT || 1337; // for local debugging choose any available port
var server = app.listen(port, function () {
var host = server.address().address;
console.log("app listening at http://%s:%s", host, port);
});
One more thing to check is whether any of the dependencies (express, mssql in your case) failed to resolve at startup. This can happen when you have the dependency missing in node_modules folder. You can check that by starting Log Stream (you can find in Azure portal app service blade). You might see error like this
Log stream
I am trying to deploy a node app into AWS EC2 Ubuntu instance, but I am getting issues. It seems like for some reason it is only listening to port 22 (the default portal for SSH), and not my HTTP port.
netstat -ntlp | grep LISTEN
AWS Security Group Settings
As you can see in the link above, I did manually include port 80 as well as others into my security group. I don't think this is a firewall issue from what I have read.
My Express server code:
const express = require('express'),
app = express(),
bodyParser = require('body-parser'),
cookieSession = require('cookie-session'),
port = 8000,
mongoose = require('mongoose'),
mongoDB = require('./keys.js').database,
passport = require('passport'),
passportSetup = require('./passportConfig'),
keys = require('./keys'),
bluebird = require('bluebird');
mongoose.Promise = bluebird;
app.listen(port, () => {
mongoose.connect(mongoDB)
.then(() => {
console.log('successfully connected to MongoDB. Listening to
port ', port);
})
.catch(() => {
console.log('error connecting to MongoDB.');
});
});
I am able to actually access my Node server, but connection is refused in the browser.
NPM Start
Anyone have any ideas?