Angular Socket.io服务手动断开重连报错:Cannot read property 'socket' of undefined
解决Socket.io断开回调中
this指向错误的问题 嘿,这个问题我太熟了!核心原因就是回调函数里的this指向不对,让我给你掰扯清楚:
你在disconnect事件里用了普通的function()作为回调,在JavaScript里,普通函数的this是动态绑定的——当socket触发disconnect事件时,这个回调里的this会指向触发事件的socket实例本身,而不是你的AppChatService类实例。这时候你访问this.socket,就相当于在socket对象上找socket属性,自然找不到,所以才会抛出ERROR TypeError: Cannot read property 'socket' of undefined。
而且还有个小细节:现在的socket.io-client版本里,this.socket.socket.connect()已经是过时写法了,直接调用this.socket.connect()就能重新连接。
给你两种简单的解决方案,选哪个都行:
方案1:用箭头函数(推荐)
箭头函数不会绑定自己的this,它会继承外层作用域的this(也就是你的服务类实例),直接把回调改成箭头函数就行:
this.socket.on('disconnect', () => { console.log('reached on disconnect function'); this.socket.connect(); // 改用最新的connect方法 });
方案2:提前保存this的引用
如果习惯用普通函数,就在构造函数里先把类实例的this存成一个变量,比如self,然后在回调里用self代替this:
constructor() { const self = this; // 保存类实例的this引用 this.socket = io.connect(this.url); this.socket.on('connect', function(){ console.log('connection established'); }); this.socket.on('disconnect', function(){ console.log('reached on disconnect function'); self.socket.connect(); // 用self访问类实例的socket }); }
最后给你贴个修改后的完整代码,直接用就行:
import * as io from 'socket.io-client'; import { Observable } from 'rxjs' export class AppChatService { private url = 'http://localhost:3000'; private socket; constructor() { this.socket = io.connect(this.url); this.socket.on('connect', () => { console.log('connection established'); }); this.socket.on('disconnect', () => { console.log('reached on disconnect function'); this.socket.connect(); }); } public disconnectManually(){ this.socket.disconnect(); console.log('disconnected manually'); } public sendMessage(message) { this.socket.emit('new-message', message); } public connectToChatroom(roomObject){ this.socket.emit('create',roomObject); } public getMessages = () => { return Observable.create((observer) => { this.socket.on('new-message', (message) => { console.log('reached get messages observable app chat service'); observer.next(message); }); }); } }
内容的提问来源于stack exchange,提问作者Valkyrie
相关产品推荐
相关产品推荐

