繁体   English   中英

将 socket.io 与平均值集成时重复出现 404 错误

[英]getting 404 error repeatedly when integrating socket.io with Mean

我正在尝试在数据库中发生更改时自动刷新列表。 到目前为止,我在控制台中反复收到此错误

在此处输入图像描述

所以找不到bug。

应用程序.js

 //importing modules
const express = require('express');
const http = require('http');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const socketIO = require('socket.io');
const errorHandler = require('./_helpers/error-handler');

const app =express();

const notice = require('./controllers/noticeController');
const employee = require('./controllers/employeeController');
const users = require('./users/users.controller');

//connect mongoDb


//on connection
mongoose.connection.on('connected',()=>{
    console.log('Connected to database');
});
mongoose.connection.on('error',(err)=>{
    if(err){
        console.log('Error in Database Connection '+err);
    }
});

const port = 3000;

//adding middleware
app.use(cors());

//body-parser
app.use(bodyParser.json());

//routes
app.use('/api', notice);
app.use('/api', employee);
app.use('/users', require('./users/users.controller'));

app.use(errorHandler);

const server = http.createServer(app);
const io = socketIO(server);
app.set('io',io);


//static files
app.use(express.static(path.join(__dirname, 'public')));

app.listen(port,()=>{
    console.log('Server started at port: '+port);
});

这是帖子并使用 socket.io 获取 API

通知控制器.js

//retrieving notice list
router.get('/notices/get',(req,res)=>{
   notice.find({}).then((notices)=>{
       res.send(notices)
   });
});

//add notice
router.post('/notice/add',(req,res,next)=>{
    const io = req.app.get('io');
    let newNotice = new notice({
        title : req.body.title,
        description : req.body.description,
        image : req.body.image
    });

    newNotice.save().then(()=>{
        io.emit('newNoticeAdded');
    });
});

那么任何人都可以帮助解决这个问题吗? 到客户端。 我使用了socket-io-client package。

ts 文件。

ngOnInit(): void {

   this.socket.on('newNoticeAdded',()=>{
     this.noticeService.getNotices()
                     .subscribe(notices => {
                      this.notices = notices;
});
   });
}

notices是要在更改时自动更新的列表。

马上,我可以发现你的代码有问题。 查看以下几行:

const server = http.createServer(app);
const io = socketIO(server);
app.set('io', io);


//static files
app.use(express.static(path.join(__dirname, 'public')));

app.listen(port, ()=>{
    console.log('Server started at port: '+ port);
});

这里发生了什么? 好吧,我们来分析一下:

  1. 您正在使用http.createServer(app)创建 HTTP ,然后,
  2. 您将服务器传递给socketIO()构造函数,之后,
  3. 您为您的应用程序设置了一些 static 文件路由,最后,
  4. 你在你的 express 应用上调用app.listen来启动 express 应用。

这里缺少什么? 你从来没有在你的 HTTP 服务器上调用过server.listen

你问为什么这很重要? 因为您的Socket.IO服务器绑定到您的 HTTP 服务器,而不是您的快速应用程序。 由于您只告诉您的快速应用程序开始接受连接,因此您的Socket.IO服务器尚未启动。

要解决这个问题,您可以在 HTTP 服务器上调用server.listen ,而不是使用 express 应用程序,如下所示:

const server = http.createServer(app);
const io = socketIO(server);
app.set('io', io);


//static files
app.use(express.static(path.join(__dirname, 'public')));

// Notice we called the listen function on your HTTP server 
// instead of your express app. Your express app will still work
// because you passed your app to the http.createServer method
server.listen(port, ()=>{
    console.log('Server started at port: '+ port);
});

哦,另外,您应该确保您的客户端代码连接到正确的地址。 比如,确保连接到服务器正在侦听的地址,而不是其他地址。 我这样说是因为您的错误图片显示您试图连接到端口 4200 而不是 3000,这是您的服务器正在侦听的端口。

编辑因为我看到您不确定如何将您的客户端连接到与您的服务器运行相同的端口,所以这里有一些代码可以帮助您。

// You could just do this, and the socket.io client
// will connect to the ```window.location```, which
// is usually what you want.
// This is good because you don't hard-code the URL
// into your code, making it easier for you to put the
// script into production.
const socket = io();

// You could also do ```io.connect```, but BEWARE,
// you have to change the URL that the socket.io client
// connects to manually, so that's why I prefer the above
// method.
const socket2 = io.connect("http://localhost:3000");

您可以在此处查看io() function 的默认行为

希望这可以帮助。

您需要在两侧使用相同的端口。 我的客户端 typescript 服务(服务器使用端口 8090):

import { Injectable } from '@angular/core';

// rxjs
import { Observable } from 'rxjs';

// other
import { NGXLogger } from 'ngx-logger';
import { Event } from '../model/event';
import { environment } from '../../../environments/environment';
import * as socketIo from 'socket.io-client';

export let SERVER: string = "";
if (environment.production) {
    SERVER = 'http://10.1.1.7:8090';    // EDS Server
} else {
    SERVER = 'http://10.1.1.194:8090';  // Portalogic PC
    //SERVER = "http://" + window.location.hostname + ":8090";
}

@Injectable({
    providedIn: "root"
})
export class SocketService {
    debug: boolean = true;
    private socket: any;

    constructor(
        private logger: NGXLogger,
      ) { }

      public initSocket(): void {
        if (this.debug) {
            this.logger.debug("initialize websocket at " + SERVER);
        }
        this.socket = socketIo(SERVER);
    }

    public closeSocket(): void {
        this.socket.close();
    }

    public sendEvent(event: Event, data?: Object): void {
        if (this.debug) {
            this.logger.debug("sendEvent >> event = " + event.toString() + "; data = " + JSON.stringify(data));
        }

        this.socket.emit(event.toString(), data);
    }

    public onEvent(event: Event): Observable<Event> {
        return new Observable<Event>(observer => {
            this.socket.on(event, (data: any) => observer.next(data));
        });
    }
}

我从app.component.ts initIoConnection订阅onEvent事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM