websockets 不适用于 https.createServer

Posted

技术标签:

【中文标题】websockets 不适用于 https.createServer【英文标题】:websockets not working with https.createServer 【发布时间】:2021-02-02 12:33:57 【问题描述】:

我们的 websocket 在 Http/express 下工作,但是当我移动到 https.createServer 时,我无法获得套接字连接。

仅供参考:项目快完成了,我们已经深入了解express-ws,所以我们在这个阶段继续更改套接字库

这是我的代码示例:

import express from 'express';
import expressWs from 'express-ws'

const app = express();
const port = 443

expressWs(app);

app.ws('/api/websocket',socketApiLogic)
app.get('/',indexLogic)
app.use(express.static(path.join(__dirname, '../build/')));
app.use('*', express.static(path.join(__dirname, '../build/404.html')));


if (process.env.prod || process.env.NODE_ENV == 'prod') 
  const server = require('https').createServer(
                                    key: fs.readFileSync(path.resolve(__dirname,'../ssl/key.pem')),
                                    cert: fs.readFileSync(path.resolve(__dirname,'../ssl/cert.pem')),
                                  , app)
  
  require('http').createServer(function (req, res) 
      res.writeHead(301,  "Location": "https://" + req.headers['host'] + req.url );
      res.end();
  ).listen(80);
  
  server.addListener('upgrade', (req, res, head) => console.log('UPGRADE:', req.url));
  server.on('error', (err) => console.error(err));
  
  server.listen(port, () => 
         console.log('= Prod mode = ' + port);
    );
  
 else 
  
  app.listen(port, () => 
        console.log('= Dev mode = ' + port);
 );


感谢您的帮助

【问题讨论】:

作为替代方法,您可以在代理级别处理 ssl 证书。这样,您的节点服务器将仅在 HTTP 上运行,而像 nginx 这样的代理将处理 SSL 和重定向。 嗨,Shaharyar,那会是什么样子?您是否有一个将 80 重定向到 433 + 使用 express App 的密钥和证书文件包装 433 的示例?谢谢 【参考方案1】:

从documentation 你可以将服务器作为第二个参数传递。

你的代码应该更像

// imports & config

import express from 'express';
import expressWs from 'express-ws'

const app = express();
const port = 443
const isProd = process.env.prod || process.env.NODE_ENV == 'prod'

if (isProd) 
  startProd()
 else 
  startLocal()

// SSL server
function startProd()

  setupPaths()

// ~~~~~~~~~~~ SETUP YOUR SSL SERVER

  const server = require('https').createServer(
                                    key: fs.readFileSync(path.resolve(__dirname,'../ssl/key.pem')),
                                    cert: fs.readFileSync(path.resolve(__dirname,'../ssl/cert.pem')),
                                  , app)
  
  require('http').createServer(function (req, res) 
      res.writeHead(301,  "Location": "https://" + req.headers['host'] + req.url );
      res.end();
  ).listen(80);
  
  server.addListener('upgrade', (req, res, head) => console.log('UPGRADE:', req.url));
  server.on('error', (err) => console.error(err));
  
  server.listen(port, () => 
         console.log('= Prod mode = ' + port);
    );

// ~~~~~~~~~~~ USE YOUR SSL SERVER

  expressWs(app,server);
  app.ws('/api/websocket',socketApiLogic)
  catchAllPaths()

// localhost server
function startLocal()

  expressWs(app);
  app.ws('/api/websocket',socketApiLogic)
  setupPaths()
  catchAllPaths()
  app.listen(port, () => 
        console.log('= Server started = ' + port);
 );

// Add paths
function setupPaths()
app.get('/',indexLogic)

function catchAllPaths()
app.use(express.static(path.join(__dirname, '../build/')));
app.use('*', express.static(path.join(__dirname, '../build/404.html')));

【讨论】:

以上是关于websockets 不适用于 https.createServer的主要内容,如果未能解决你的问题,请参考以下文章

使用 nginx 的 Websocket 代理不适用于 tomcat。

PHP websocket不适用于safari,标头修改

SSL WebSocket 连接不适用于 webkit 浏览器?

Springboot WebSocket TextWebSocketHandler 不适用于 json 消息

Google Container Engine (Kubernetes):Websocket (Socket.io) 不适用于多个副本

Cookie不适用于Apple设备上的WebSocket