Angular5项目使用angular2-websocket报错:No provider for $WebSocket
解决 Angular5 中 angular2-websocket 的 NullInjectorError 问题
这个错误的核心原因是你对angular2-websocket的使用方式有误——$WebSocket并不是一个可以通过Angular依赖注入系统直接注入的服务,而是需要手动实例化的类,再加上你在构造函数里的错误注入逻辑,才导致了NullInjectorError: No provider for $WebSocket。
具体问题分析
- 你在组件构造函数中尝试注入
$WebSocket,但这个库的$WebSocket是普通类,不是Angular标记为@Injectable的服务,依赖注入系统找不到它的提供者。 - 构造函数里的
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
相关产品推荐
相关产品推荐

