简体   繁体   中英

getting 404 error repeatedly when integrating socket.io with Mean

I'm trying to automatically refresh list when a change is happend in database. so far i'm getting this error in console reapeatedly

在此处输入图像描述

so can't find the bug.

app.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);
});

and here is the post and get API with socket.io

noticeController.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');
    });
});

so can anyone help with this matter? to client side. I have use socket-io-client package.

ts file.

ngOnInit(): void {

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

notices is the list that want to update automatically on change.

Right away, I could spot something fishy with your code. Look at the following lines:

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);
});

What is happening here? Well, let's analyze:

  1. You are creating a HTTP using http.createServer(app) , then,
  2. You are passing the server to the socketIO() constructor, after that,
  3. You set up some static file routes for your app, finally,
  4. You call app.listen on your express app to start the express app.

What is missing here? You never called server.listen on your HTTP server!

Why is that important, you ask? Because your Socket.IO server is bound to your HTTP server, not your express app. Since you only told your express app to start accepting connections, your Socket.IO server hasn't been started.

To solve this, you could just call server.listen on your HTTP server instead of you express app, like this:

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);
});

Oh, and also, you should make sure your client-side code is connecting to the correct address. Like, make sure you connect to the address that your server is listening on, not some other address. I'm saying this because your error pictures show that you were trying to connect to port 4200 instead of 3000, which is what your server is listening on.

EDIT Since I saw you weren't sure how to connect your client to the same port as your server is running on, here's some code to help you out.

// 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");

You can see the default behaviour of the io() function here

Hope this helps.

You need to use the same port on both sides. My client side typescript service (server is using port 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));
        });
    }
}

I call initIoConnection from app.component.ts then subscribe to onEvent events.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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