spdy-http2 / node-spdy

SPDY server on Node.js
2.81k stars 196 forks source link

Server fails to start with express and typescript #319

Open SatioO opened 7 years ago

SatioO commented 7 years ago

Tried to plug in spdy in my exsiting angular project. It is running well with the existing node http and https module. but when I run same code with spdy, It fails to start.

Below is my code and error response:

`import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import 'rxjs/Rx';
import * as express from 'express';
import compression from 'compression';
import favicon from 'serve-favicon';``
import { ServerAppModule } from './app/server-app.module';
import { ngExpressEngine } from './modules/ng-express-engine/express-engine';
import { ROUTES } from './routes';
import { enableProdMode } from '@angular/core';
import { EnvironmentManager } from './confighelpers'; 

enableProdMode();

const environmentManager = new EnvironmentManager(process.env.NODE_ENV);

// const http2 = require('spdy');
import * as http2 from 'spdy';
const fs = require('fs');
const path = require('path');
const app = express();
const port = environmentManager.getPort();
const baseUrl = `http://localhost:${port}`;

app.use(compression());

app.engine('html', ngExpressEngine({
  bootstrap: ServerAppModule
}));

app.set('view engine', 'html');
app.set('views', environmentManager.getViewsPath());

app.use('/assets', express.static(environmentManager.getAssetsPath()));
app.use(express.static(environmentManager.getStaticPath(), { index: false }));

let bootstrap = fs.readFileSync('./assets/styles/bootstrap.min.css');
let mainstyle = fs.readFileSync('./assets/styles/style.css');

// ROUTES.forEach(route => {

  app.get('/', (request, response) => {

    // console.log(response.push);
    // let headers = {
    //   'content-type': 'text/css; charset=UTF-8'
    // }

    // response.push('./assets/styles/bootstrap.min.css', headers, function(err, stream){
    //   if (err) return;
    //   stream.end(bootstrap);
    // });

    // response.push('./assets/styles/style.css', headers, function(err, stream){
    //   if (err) return;
    //   stream.end(mainstyle);
    // });

    // response.push('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', headers, function(err, stream){
    //   if (err) return;
    //   stream.end('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
    // });

    // response.writeHead(200, {'content-type': 'text/html'});
    // var message = "No SPDY for you!"
    // if (request.isSpdy){
    //   message = "YAY! SPDY Works!"
    // }
    response.end("" +
    "<html>" + 
      "<head>" +
        "<title>First SPDY App!</title>" +
        "<link href='./assets/styles/bootstrap.min.css' rel='stylesheet'>" +
        "<link href='./assets/styles/style.css' rel='stylesheet'>" +
        "<link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' rel='stylesheet' />"+
      "<head>" +
      "<body>" +
        "<h1>" + "message" + "</h1>" +
      "</body>" +
    "<html>");

  // });
});

const options = {
  key: fs.readFileSync('./assets/certificates/server.key'),
  cert: fs.readFileSync('./assets/certificates/server.crt')
}

http2
  .createServer(options, app)
  .listen(port, "0.0.0.0", () => {
    console.log(`App started listening on PORT ${port}`);
  });
`

` ERROR in /home/vaibhav/Desktop/ng-inspinia/src/main.server.ts (91,26): Argument of type 'Express' is not assignable to parameter of type '(request: IncomingMessage, response: ServerResponse) => void'.
      Types of parameters 'res' and 'response' are incompatible.
        Type 'ServerResponse' is not assignable to type 'Response'.
          Property 'status' is missing in type 'ServerResponse'.

npm ERR! Linux 4.8.0-49-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "run" "build"
npm ERR! node v7.9.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! ng-inpsinia@1.0.0 build: `webpack`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the ng-inpsinia@1.0.0 build script 'webpack'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the ng-inpsinia package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     webpack
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs ng-inpsinia
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls ng-inpsinia
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/vaibhav/.npm/_logs/2017-05-21T11_42_23_190Z-debug.log

npm ERR! Linux 4.8.0-49-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "run" "start"
npm ERR! node v7.9.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! ng-inpsinia@1.0.0 start: `npm run build && npm run server`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the ng-inpsinia@1.0.0 start script 'npm run build && npm run server'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the ng-inpsinia package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run build && npm run server
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs ng-inpsinia
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls ng-inpsinia
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/vaibhav/.npm/_logs/2017-05-21T11_42_23_217Z-debug.log

and here is my typescript defination file:

{ "compilerOptions": { "moduleResolution": "node", "module": "es2015", "target": "es5", "noImplicitAny": false, "sourceMap": false, "experimentalDecorators": true, "emitDecoratorMetadata": true, "lib": [ "es2016", "dom" ] }, "include": [ "src" ] }

jcheenatcode commented 7 years ago

I am having the same issue. Node Version - 6.11.2 NPM Version - 3.10.10 Express - 4.14.0 Windows 10

import * as express from "express";
import * as helmet from "helmet";
import * as morgan from "morgan";
import * as compression from "compression";
import * as bodyParser from "body-parser";
import * as fs from "fs";
import * as spdy from "spdy";

export class Server {
    app = express();
    options = {
        key: fs.readFileSync(__dirname + '/server.key'),
        cert:  fs.readFileSync(__dirname + '/server.crt')
    };

    constructor(private port: number) {
        this.configureMiddleware();
        this.configureRoutes();
    }

    private configureMiddleware() {
        console.info("Configuring middleware...");

        this.app.use(helmet());
        this.app.use(compression());
        this.app.use(bodyParser.urlencoded({ extended: true }));
        this.app.use(bodyParser.json());
        this.app.use(express.static('public'));
        this.app.use(morgan('dev'));
    }

    private configureRoutes() {
        console.info("Configuring routes...");
    }

    public start() {        
        spdy
            .createServer(this.options, this.app)
            .listen(this.port, (error:any) => {
                if (error) {
                    console.error(error);
                    return process.exit(1);
                } else {
                    console.log('Listening on port: ' + this.port + '.');
                }
            });
    }
}
jcheenatcode commented 7 years ago

May be an issue not because of this module itself, but the typed definitions written for it ... https://github.com/DefinitelyTyped/DefinitelyTyped/blob/354cec620daccfa0ad167ba046651fb5fef69e8a/types/spdy/index.d.ts

Are there any recommendations as to how we can resolve this issue?

Thanks

jcheenatcode commented 7 years ago

@SatioO Were you able to figure out how to fix this issue?

chrstntdd commented 7 years ago

Having the same issue setting up spdy with express.

import { readFileSync } from 'fs';

import api from './api';

const spdy = require('spdy');
const mongoose = require('mongoose');
require('dotenv').config();

/* Instantiate our app instance */
const app: api = new api();

/* required for ssl encryption and http2 */
const options = {
  key: readFileSync(__dirname + '/../server.key'),
  cert: readFileSync(__dirname + '/../server.crt')
};

/* Get current environment */
const env = app.currentEnv();

let DATABASE_URL;
let PORT;

/* set environment variables */
if (env === 'production') {
  DATABASE_URL = process.env.MONGODB_URI;
  PORT = process.env.PORT;
} else {
  DATABASE_URL = process.env.TEST_DATABASE_URL;
  PORT = 3000;
}

/* Set mongoose promise to native ES6 promise */
mongoose.Promise = global.Promise;

const connectOptions = {
  useMongoClient: true,
  keepAlive: true,
  reconnectTries: Number.MAX_VALUE
};

/* Both runServer and closeServer need access to the server var,
 * so it's declared outside of both function.
 */
let server;

export const runServer = async (
  databaseUrl: string = DATABASE_URL,
  port: number | string = PORT
) => {
  try {
    await mongoose.connect(databaseUrl, connectOptions);
    await new Promise((resolve, reject) => {
      server = spdy
        .createServer(options, app)
        .listen(port, () => {
          console.info(
            `Your server is listening on port ${port} with the db ${databaseUrl} in a ${env} environment🤔`
          );
          resolve();
        })
        .on('error', err => {
          mongoose.disconnect();
          reject(err);
        });
    });
  } catch (err) {
    console.error(err);
  }
};

export const closeServer = async () => {
  try {
    await mongoose.disconnect();
    await new Promise((resolve, reject) => {
      console.info(`Closing server. Goodbye old friend.`);
      server.close(err => {
        if (err) return reject(err);
        return resolve();
      });
    });
  } catch (err) {
    console.error('error');
  }
};

if (require.main === module) {
  runServer().catch(err => console.error(err));
}

Throws error TypeError: "listener" argument must be a function at the line where I call .createServer()

gKreator commented 6 years ago

@chrstntdd the app parameter in .createServer(options, app) needs to be an instance of express() https://webapplog.com/http2-node/

StEvUgnIn commented 3 years ago

@chrstntdd the app parameter in .createServer(options, app) needs to be an instance of express() https://webapplog.com/http2-node/

It is year 2021, ans I still encounter this problem. I tried setting app as instance of Express but the returned error is the same as usual:

TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object at checkListener (events.js:112:11) at _addListener (events.js:348:3) at Server.addListener (events.js:406:10)