【问题标题】:Angular with Socket.io: Uncaught ReferenceError: WebSocket is not defined at Object../node_modules/engine.io-client/lib/transports/websocket.js带有 Socket.io 的 Angular:未捕获的 ReferenceError:WebSocket 未在 Object../node_modules/engine.io-client/lib/transports/websocket.js 中定义
【发布时间】:2020-08-30 01:35:12
【问题描述】:

我尝试将 Socket.io 实现到我的 Angular Web 应用程序中,该应用程序与使用 express 的简单 api 服务器结合运行(在 THIS 的示例之后)。

我按顺序使用npm startng serve 启动服务器和客户端,但是当我尝试在浏览器中的 localhost:4200 访问应用程序时,开发者控制台显示以下错误:

服务器文件结构:

客户端文件结构:

www.js(主服务器文件)

#!/usr/bin/env node

/**
 * Module dependencies.
 */
const app = require('../app'),
      debug = require('debug')('angular-node-express-api:server'),
      http = require('http'),
      server = http.createServer(app),
      io = require('socket.io')(server);

let timerId = null,
    sockets = new Set();

// Run this on new Socket connection
//
io.on('connection', socket => {

  sockets.add(socket);
  console.log(`Socket ${socket.id} added`);

  if (!timerId) {
    startTimer();
  }

  socket.on('clientdata', data => {
      console.log(data);
  });

  socket.on('disconnect', () => {
    console.log(`Deleting socket: ${socket.id}`);
    sockets.delete(socket);
    console.log(`Remaining sockets: ${sockets.size}`);
  });

});

// Timer function for Socket IO, simulates changing data, pushing that data to connected clients.
//
function startTimer() {
  //Simulate stock data received by the server that needs
  //to be pushed to clients
  timerId = setInterval(() => {
    if (!sockets.size) {
      clearInterval(timerId);
      timerId = null;
      console.log(`Timer stopped`);
    }
    let value = ((Math.random() * 50) + 1).toFixed(2);
    //See comment above about using a "room" to emit to an entire
    //group of sockets if appropriate for your scenario
    //This example tracks each socket and emits to each one
    for (const s of sockets) {
      console.log(`Emitting value: ${value}`);
      s.emit('data', { data: value });
    }

  }, 2000);
}

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
console.log('Server is now listening on port ' + port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

data.service.ts(客户端的socket服务,见错误信息)

console.log("At least you've tried.");
import { Injectable } from '@angular/core';
import { map, catchError } from 'rxjs/operators';
import * as socketIo from 'socket.io-client';
import { Socket } from '../shared/interfaces';
import { Observer, Observable } from 'rxjs';

declare var io : {
  connect(url: string): Socket;
};

@Injectable()
export class DataService {

  socket: Socket;
  observer: Observer<number>;

  getQuotes() : Observable<number> {
    this.socket = socketIo('http://localhost:3000');

    this.socket.on('data', (res) => {
      this.observer.next(res.data);
    });

    return this.createObservable();
  }

  createObservable() : Observable<number> {
      return new Observable<number>(observer => {
        this.observer = observer;
      });
  }

  private handleError(error) {
    console.error('server error:', error);
    if (error.error instanceof Error) {
        let errMessage = error.error.message;
        return Observable.throw(errMessage);
    }
    return Observable.throw(error || 'Socket.io server error');
  }

}

package.json(客户端)

{
  "name": "ody-network-webui",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "proxy-start": "ng serve --proxy-config proxy.conf.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~9.1.4",
    "@angular/cdk": "^9.2.2",
    "@angular/common": "~9.1.4",
    "@angular/compiler": "~9.1.4",
    "@angular/core": "~9.1.4",
    "@angular/forms": "~9.1.4",
    "@angular/localize": "~9.1.4",
    "@angular/material": "^9.2.2",
    "@angular/platform-browser": "~9.1.4",
    "@angular/platform-browser-dynamic": "~9.1.4",
    "@angular/router": "~9.1.4",
    "@ng-bootstrap/ng-bootstrap": "^6.1.0",
    "@types/express": "^4.17.6",
    "@types/fast-text-encoding": "^1.0.1",
    "@types/socket.io": "^2.1.4",
    "bootstrap": "^4.4.0",
    "core-js": "^3.6.5",
    "csvtojson": "^2.0.10",
    "ejs": "^3.1.2",
    "express-ejs-layouts": "^2.5.0",
    "fast-text-encoding": "^1.0.2",
    "rxjs": "^6.5.5",
    "socket.io": "^2.3.0",
    "socket.io-client": "^2.3.0",
    "tslib": "^1.10.0",
    "ws": "^7.2.5",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.901.4",
    "@angular/cli": "~9.1.4",
    "@angular/compiler-cli": "~9.1.4",
    "@angular/language-service": "~9.1.4",
    "@types/csvtojson": "^1.1.5",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.12.38",
    "@types/socket.io-client": "^1.4.32",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~3.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "protractor": "~5.4.3",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.8.3"
  }
}

我对这个问题非常迷茫,还没有找到任何解决方案。

【问题讨论】:

  • 无法真正找到解决此问题的方法,可能与错误的依赖项或软件包有关。最后我生成了一个新项目,手动安装了所需的依赖项并复制了大部分代码。

标签: javascript html node.js angular socket.io


【解决方案1】:

看到这个答案https://stackoverflow.com/a/55616176/14665845

在带有 ES6 或类似的 nodeJS 应用程序中,您必须使用这个:

global.WebSocket = require('ws')

例如:

import { WebSocketSubject, webSocket } from 'rxjs/webSocket';

global.WebSocket = require('ws'); // <-- FIX ALL ERRORS
const subject = webSocket('ws://...');

没有更多错误。

【讨论】:

    猜你喜欢
    • 2020-03-15
    • 2019-12-30
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多