部署后 Socket.io 不工作 - 抛出错误 - 405(不允许)

Posted

技术标签:

【中文标题】部署后 Socket.io 不工作 - 抛出错误 - 405(不允许)【英文标题】:Socket.io is not working after deployment - throwing an error - 405 (Not Allowed) 【发布时间】:2020-04-19 09:36:00 【问题描述】:

使用 Angular 和 Node.js 构建应用程序。集成使用 Socket.io 构建的聊天应用程序。 在本地测试时工作正常。即使在将 Node JS 后端部署到服务器机器(AWS EC2 实例)之后,我们的本地 Angular 应用程序也可以访问后端服务器。 但在 EC2 中部署 Angular 应用程序后,聊天模块无法正常工作并抛出错误“POST https://mysitedotcom/socket.io/?EIO=3&transport=polling&t=MzNa0m-405 (Not Allowed)” 请在下面找到服务器端代码。

require('./global_constants');

const Knex = require('knex');
const morgan = require('morgan');
const express = require('express');
const bodyParser = require('body-parser');
const promiseRouter = require('express-promise-router');
const rs = require('rocket-store');
const knexConfig = require('./knexfile');
const registerApi = require('./api');
const adminName = require('./config/config').admin.name;
const dbObj = require('./controllers/dbConn');
const cleaner = require('./controllers/textCleaner');
const fs = require('fs');
const rimraf = require('rimraf');
const socketIO = require('socket.io');
const db = dbObj.db;

const 
  Model
 = require('objection');
const cors = require('cors');

const knex = Knex(knexConfig[process.env.NODE_ENV || 'production']);

Model.knex(knex);

const router = promiseRouter();

const app = express()
  .use(bodyParser.json())
  .use(morgan('dev'))
  .use(cors(
    
      credentials: true,
      origin: ['http://localhost:4200', 'http://localhost:4201']
    
  ))

app.use('/api/', router).set('json spaces', 2);

app.use((req, res, next) => 
  res.setHeader('Content-Type', 'application/json');
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
)


registerApi(router);

app.use((err, req, res, next) => 
  if (err) 
    console.error(err);
    res.status(err.statusCode || err.status || 500).send(err || );
   else 
    next();
  
);

const http = require('https').createServer(app);
const io = socketIO(http);
http.listen(3000, function () 
  console.log('listening on *:3000');
);

rs.options(
  data_storage_area: "./msg",
  data_format: rs._FORMAT_JSON,
);


io.on('connection', socket => 
  socket.on('new-user', async (room, userId) => 
    // some logic goes here
  )

  socket.on('new-message', async (room) => 
    // Some logic
  )

  socket.on('user-disconnect', async (room, userId) => 
    // Some logic
  )
)

请在下面找到客户端代码

import  Injectable  from '@angular/core';
import * as io from 'socket.io-client';
import  Observable  from 'rxjs';

@Injectable(
  providedIn: 'root'
)
export class ChatService 

  private socket;
  constructor() 
    this.socket = io();
  

  public newUser(roomName, id) 
    this.socket.emit('new-user', id, roomName);
  
  public userDisconnected(roomName,id)
    this.socket.emit('user-disconnect',roomName,id)
  

  public sendMessage(roomName, message,fullname,) 
    this.socket.emit('new-message',roomName,message,fullname);
  

  public getconnect = () =>
    return Observable.create((observer) => 
      this.socket.on('user-connected', (message,prev,socketId,flag) => 
          observer.next(msg:message,all_prev_msg:prev,socketId:socketId);
      );
    );
  
  public getDisconnected = () =>
    return Observable.create((observer) => 
      this.socket.on('user-disconnected', (message) => 
          observer.next(message);
      );
    );
  

  public getMessages = () => 
    return Observable.create((observer) => 
      this.socket.on('new-message', (room,message,userId) => 
          observer.next(text:message,sender:userId);
      );
    );
  


如果有人还有其他问题,请告诉我。 非常感谢。

【问题讨论】:

【参考方案1】:

看起来你的 ec2 服务器中有 nginx,如果是,你需要下面的配置

location /static 
    try_files $uri =404;


location /socket.io 
        proxy_pass http://node;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        add_header  Front-End-Https   on;


error_page 405 @nodejs;

【讨论】:

以上是关于部署后 Socket.io 不工作 - 抛出错误 - 405(不允许)的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io 移动到不同的域名后抛出 connect_error “服务器错误”

Socket.io 在 localhost 上工作,但在部署 heroku 后无法工作?

socket io连接在localhost中正常工作,但在heroku服务器上部署时却没有

Socket.io 安装抛出 Missing required argument 错误

Heroku Node.js + Socket.io:部署到 Heroku 后,我得到一个 ERR_CONNECTION_REFUSED

Socket.io 无法正常工作