You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular5项目使用angular2-websocket报错:No provider for $WebSocket

解决 Angular5 中 angular2-websocket 的 NullInjectorError 问题

这个错误的核心原因是你对angular2-websocket的使用方式有误——$WebSocket并不是一个可以通过Angular依赖注入系统直接注入的服务,而是需要手动实例化的类,再加上你在构造函数里的错误注入逻辑,才导致了NullInjectorError: No provider for $WebSocket。

具体问题分析

  1. 你在组件构造函数中尝试注入$WebSocket,但这个库的$WebSocket是普通类,不是Angular标记为@Injectable的服务,依赖注入系统找不到它的提供者。
  2. 构造函数里的chatData、message、user都是组件的本地状态属性,不应该放在构造函数中注入,应该直接在组件内声明并初始化。

修复步骤及修改后的代码

1. 修正组件代码

移除构造函数中的错误注入,手动实例化$WebSocket,并修正几个细节问题:

import { Component, OnInit } from '@angular/core';
import { $WebSocket, WebSocketSendMode } from 'angular2-websocket/angular2-websocket';

interface ChatModel {
  user: string; // TypeScript推荐使用小写原始类型string,而非包装对象String
  message: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'Websockets Chat Using Angular 2 Sockets And Django Channels';
  // 声明组件本地属性并初始化
  private mysocket?: $WebSocket;
  public chatData: ChatModel[] = [];
  public message: string = '';
  public user: string = '';

  // 构造函数无需注入多余内容
  constructor() {}

  onChatSubmit() {
    // 先判断socket实例是否存在,避免报错
    if (!this.mysocket) return;
    
    const datatoSend = JSON.stringify({
      'user': this.user,
      'message': this.message
    });
    this.mysocket.send(datatoSend);
    this.message = ''; // 发送后清空输入框
  }

  addChatItem(msg: MessageEvent) {
    this.chatData.push(JSON.parse(msg.data));
  }

  ngOnInit() {
    // 修正URL拼写错误:ws// -> ws://,IP地址修正为127.0.0.1
    this.mysocket = new $WebSocket('ws://127.0.0.1:8000');
    this.mysocket.setSend4Mode(WebSocketSendMode.Direct);
    // 绑定this,确保回调函数中的this指向组件实例
    this.mysocket.onMessage(this.addChatItem.bind(this));
  }
}

2. 关键细节说明

  • 手动实例化$WebSocket:取消注释你原本在ngOnInit中的实例化代码,这才是正确使用这个库的方式。
  • 绑定this:在onMessage回调中必须绑定组件的this,否则回调函数里的this会指向$WebSocket实例,导致无法访问组件的chatData属性。
  • 初始化本地属性:给chatData、message、user设置初始值,避免出现undefined导致的后续报错。

可选:封装为可注入服务(多组件复用场景)

如果你的应用需要在多个组件中复用同一个WebSocket连接,可以封装成Angular服务:

// web-socket.service.ts
import { Injectable } from '@angular/core';
import { $WebSocket, WebSocketSendMode } from 'angular2-websocket/angular2-websocket';

@Injectable({
  providedIn: 'root' // 自动注册到根模块,无需手动添加到providers
})
export class WebSocketService {
  private socket?: $WebSocket;

  connect(url: string) {
    this.socket = new $WebSocket(url);
    this.socket.setSend4Mode(WebSocketSendMode.Direct);
    return this.socket;
  }

  getSocket() {
    return this.socket;
  }
}

然后在组件中注入使用:

// AppComponent构造函数
constructor(private webSocketService: WebSocketService) {}

ngOnInit() {
  const socket = this.webSocketService.connect('ws://127.0.0.1:8000');
  socket.onMessage(this.addChatItem.bind(this));
  this.mysocket = socket;
}

内容的提问来源于stack exchange,提问作者WAS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:57:18