javascript - 调用节点模块中的类中的函数时获取“无法读取未定义的属性”
问题描述
这是我的代码:
从模块的 index.js 中:
class TSL5 extends EventEmitter {
constructor () {
super()
//Message Format
this._PBC = 0 //offset
this._VER = 2
this._FLAGS = 3
this._SCREEN = 4
this._INDEX = 6
this._CONTROL = 8
this._LENGTH = 10
}
listenUDP(port) {
this.server = dgram.createSocket('udp4')
this.server.bind(port)
this.server.on('message',(msg, rinfo) => {
this.processTally(msg,rinfo)
debug('Message recieved: ', msg)
})
this.server.on('listening', () => {
var address = this.server.address();
debug(`server listening ${address.address}:${address.port}`);
});
this.server.on('error', (err) => {
debug('server error: ', err);
throw err;
});
return this.server;
}
processTally(data,rinfo) {
let buf = Buffer.from(data)
let tally = { display: {} }
tally.sender = rinfo.address
tally.pbc = buf.readInt16LE(this._PBC)
tally.ver = buf.readInt8(this._VER)
tally.flags = buf.readInt8(this._VER)
tally.screen = buf.readInt16LE(this._SCREEN)
tally.index = buf.readInt16LE(this._INDEX)
tally.control = buf.readInt16LE(this._CONTROL)
tally.length = buf.readInt16LE(this._LENGTH)
tally.display.text = buf.toString('ascii', this._LENGTH+2)
tally.display.rh_tally = (tally.control >> 0 & 0b11);
tally.display.text_tally = (tally.control >> 2 & 0b11);
tally.display.lh_tally = (tally.control >> 4 & 0b11);
tally.display.brightness = (tally.control >> 6 & 0b11);
tally.display.reserved = (tally.control >> 8 & 0b1111111);
tally.display.control_data = (tally.control >> 15 & 0b1);
this.emit('message',tally)
}
然后是服务器端 index.js:
let umd = new TSL5;
for (let i = 0; i < source_connections.length; i++) {
if (source_connections[i].sourceId === sourceId) {
AddPort(port, sourceId);
logger(`Source: ${source.name} Creating TSL 5.0 UDP Connection.`, 'info-quiet');
//source_connections[i].server = dgram.createSocket('udp4');
//source_connections[i].server.bind(port);
source_connections[i].server = umd.listenUDP(port);
source_connections[i].server.on('message', function (message) {
processTSL5Tally(sourceId, message);
});
logger(`Source: ${source.name} TSL 5.0 Server started. Listening for data on UDP Port: ${port}`, 'info');
for (let j = 0; j < sources.length; j++) {
if (sources[j].id === sourceId) {
sources[j].connected = true;
break;
}
}
UpdateSockets('sources');
UpdateCloud('sources');
break;
}
}
每当我尝试调用下部代码块所在的函数时,都会收到Cannot read property 'on' of undefined
错误消息。消除错误的唯一方法是将 a 添加return this.server
到listenUDP
函数中。但是,如果我这样做,那么该函数应该通过该processTally
函数发出的所有数据都将丢失。
解决方案
您当前的问题是由这些行引起的:
source_connections[i].server = umd.listenUDP(port);
source_connections[i].server.on('message', function (message) {
processTSL5Tally(sourceId, message);
});
source_connections[i].server
是调用的结果listenUDP
。因此,如果您不返回服务器(通过return this.server
),那么就没有什么可调用.on
的了。
返回服务器会导致您遇到的另一个问题:
// in processTally
this.emit('message',tally)
但是在你的循环中,你在打电话
source_connections[i].server.on('message', function (message) {
事件发射器本身正在发射这个新的“消息”,但您仍在“事件发射器的服务器”上监听。发射器(TSL5 类)是服务器的包装器。因此,您应该监听事件发射器,而不是监听服务器的消息,它也会发出“消息”,这是处理内部服务器消息的结果:
// just the emitter, not the server
source_connections[i].on('message', function (message) {
processTSL5Tally(sourceId, message);
});
作为旁注 - 请记住您有一个发射器实例。因此,如果该循环多次运行(针对不同的连接),事情就会变得混乱。因此,您可能需要为每次迭代创建新的发射器,但不确定这是否是您的情况。
推荐阅读
- python - 尝试在熊猫中删除行时出错
- node.js - 如何使用2参数路由获取node.js
- javascript - React Native Expo 键盘每次按下都会关闭
- docker - 从 Hashicorp-Vault 服务器获取 .env 变量,在本地机器上运行 Docker 映像
- html - 具有行跨度的单元格中的文本框不应用宽度值
- javascript - 如何从 react-google-maps/api 获取可编辑折线的更新路径?
- r-markdown - 使用 bookdown book 中定义和说明的自定义块
- inheritance - 将具体课程定为最终课程是一种好习惯吗?
- python - TypeError:“节点”和“节点”的实例之间不支持“<”
- ios - Firebase 函数 iOS:响应不是字典