socketio / socket.io

Realtime application framework (Node.JS server)
https://socket.io
MIT License
61.17k stars 10.11k forks source link

Failed to connect to websocket using wss #4725

Closed Tyh2001 closed 1 year ago

Tyh2001 commented 1 year ago

Describe the bug

I use socket. io to implement websocket, which can connect normally in the development environment. Both the front-end and back-end are deployed to the production environment, but the connection using wss failed.

WebSocket connection to 'wss://xxxxx:7171/socket.io/?EIO=4&transport=websocket' failed:
连接失败 Error: websocket error
    at a5.onError (index-5d19907a.js:12:36135)
    at ws.onerror (index-5d19907a.js:12:42813)

To Reproduce

Please fill the following code example:

Socket.IO server version: 4.6.1

Server

import {
  WebSocketGateway,
  SubscribeMessage,
  MessageBody,
  ConnectedSocket,
  OnGatewayConnection,
  WebSocketServer,
  OnGatewayInit,
} from '@nestjs/websockets'
import { Socket, Server } from 'socket.io'
import { ChatList } from './entity/chat.entity'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'

@WebSocketGateway(7171, {
  cors: {
    origin: ['https://xxxxx.cn', 'http://localhost:8888'],
    credentials: true,
  },
  transports: ['websocket'],
})
export class ChatGateway implements OnGatewayConnection {
  constructor(
    @InjectRepository(ChatList)
    private chatListEntity: Repository<ChatList>
  ) {}

  @WebSocketServer()
  server: Server = new Server()

  handleConnection(client: Socket) {
    client.join('room')
  }

  @SubscribeMessage('chat')
  async handleMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() payload
  ) {
    try {
      const newChat = this.chatListEntity.create(JSON.parse(payload))

      await this.chatListEntity.save(newChat)
    } catch (err) {
      console.log(err)
    }

    this.server.to('room').emit('chat', payload)
  }
}

Socket.IO client version: 4.6.1

Client

const socket: Socket = io(import.meta.env.VITE_WEBSOCKET, {
  transports: ['websocket'],
})

socket.on('connect', () => {
  console.log('ok')
})

Main.ts

import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { ExpressAdapter } from '@nestjs/platform-express'
import * as express from 'express'
import * as fs from 'fs'
import * as https from 'https'
import { IoAdapter } from '@nestjs/platform-socket.io'
import { ExtendedSocketIoAdapter } from './socket'
import { corsMiddleware } from './middleware'

async function bootstrap() {
  const server = express()

  const app = await NestFactory.create(AppModule, new ExpressAdapter(server))

  app.enableCors()

  app.use(corsMiddleware)

  if (process.env.NODE_ENV === 'production') {
    const httpsOptions = {
      key: fs.readFileSync('/xxxxx/xxxx.key'),
      cert: fs.readFileSync('/xxxxx/xxxx.pem'),
    }

    const httpsServer = await https.createServer(httpsOptions, server)

    app.useWebSocketAdapter(new IoAdapter(httpsServer))

    await app.init()

    await httpsServer.listen(1216, () => {
      console.log('生产环境端口 1216 已经启动')
    })
  } else {
    await app.listen(1216, () => {
      console.log('开发环境 1216 端口已经启动')
    })
  }
}
bootstrap()

Nginx

server {
    listen 80 ssl;

    ssl_certificate_key /xxx/xxx.key;
    ssl_certificate /xxx/xxx.pem;

    # 可选的 SSL 配置
    ssl_protocols TLSv1.2 TLSv1.3;  # 指定 SSL/TLS 协议版本
    ssl_prefer_server_ciphers on;  # 优先使7171用服务器端密码套件
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';  # 指定密码套件
    ssl_session_timeout 1d;  # SSL 会话超时时间

    location /socket.io/ {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;

      proxy_pass http://localhost:7171;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }

Expected behavior

Successfully connected using wss

Platform:

Additional context

Currently, I can run normally in the local Windows development environment. However, when both the frontend and backend are deployed to the server, the WebSocket connection fails. I have placed the business code and WebSocket code in the same NestJS backend project because I want to access the data through port 1216, which is currently working fine. However, the WebSocket connection fails. I have configured the server's proxy settings, but it has not resolved the issue. If the information I provided is incomplete, feel free to ask me for more detailed configuration information.

013a151162142d640d2484fcaa92851 d3710617d8b48ae154023f310f958ff 8e8896a1160cc48770abad1162eec34
johnathancastroobs commented 1 year ago

I am experiencing the same problem, did you find a solution for this?

thc282 commented 3 months ago

same. but me on cloud run still finding the solutions