javascript - 如何为 Discord 网关设置心跳功能
问题描述
对于解决一个问题,这不会是一个非常具体的问题,因此对此表示歉意。这是我之前询问的关于获取我的 Discord 机器人网站的实时服务器数量的问题的后续。在我看来,websocket 连接是获取此信息的最佳方式,因为通过 discord.js 获取此信息占用了太多内存,因为 discord.js 所做的远远超出了我的需要。
我知道对于 websocket 连接,我需要获取连接 URL,连接,然后进行心跳并接收心跳确认。不过,实际上将这些想法转化为代码时,我遇到了很多麻烦。到目前为止,我可以请求一个 URL、连接并开始心跳,但我不知道如何 1)在接收信息的同时保持心跳,以及 2)如果连接中断(我没有收到确认)停止心跳。引起我问题的主要原因是无法与多个消息侦听器一起工作。如果有人能指出我正确的总体方向或解决我当前问题的方法,将不胜感激。
当前代码,如果它有帮助(我知道它并没有真正起作用):
const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest
const WebSocket = require('ws')
let xhr = new XMLHttpRequest()
xhr.onload = (req, res) => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
main(JSON.parse(xhr.responseText))
} else {
console.error(`ReadyState: ${xhr.readyState} Status: ${xhr.status}`)
}
}
xhr.open("GET", 'https://discord.com/api/gateway/bot', false)
xhr.setRequestHeader("Authorization", "MY_BOT_TOKEN_THIS_IS_A_PLACEHOLDER_DONT_TELL_ME_ITS_WRONG_IN_COMMENTS")
xhr.send()
function main(response) {
let socket = new WebSocket(`${response.url}/?v=6&encoding=json`)
var hello
socket.onopen = (event) => {
console.log("Connection established")
}
socket.onclose = (event) => {
console.log(`Connection closed: code=${event.code} reason=${event.reason}`)
}
socket.addEventListener('message', (event) => {
console.log(`Data received: ${event.data}`)
hello = JSON.parse(event.data)
if (hello.op == 10) {
let alive = true
heartbeat(socket, hello.s, hello.d.heartbeat_interval, alive)
socket.send(JSON.stringify({
"op": 2,
"d": {
"token": "MY_BOT_TOKEN_THIS_IS_A_PLACEHOLDER_DONT_TELL_ME_ITS_WRONG_IN_COMMENTS",
"properties": {
"$os": "windows",
"$device": "test",
"$browser": "test"
},
"guild_subscriptions": false,
"intents": 1
}
}))
socket.removeEventListener('message')
socket.addEventListener('message', (event) => {
if (JSON.parse(event.data).op !== 11) {
console.log(`Message received: ${event.data}`)
}
})
}
})
}
function heartbeat(socket, s, interval, alive) {
socket.send(JSON.stringify({"op": 1, "d": s}))
console.log("Heartbeat sent")
setTimeout(() => {
alive = false
}, interval)
}
function listenForMessage(event) {
if (JSON.parse(event.data).op === 11) {
let data = JSON.parse(event.data)
console.log(`Heartbeat received: ${event.data}`)
if (data.hasOwnProperty("s")) {
s = data.s
}
socket.removeEventListener('message')
if (alive) {
heartbeat(socket, s, interval)
socket.addEventListener('message', listenForMessage)
}
} else {
}
}
解决方案
我有一些建议。
let alert
是在错误的地方。它应该在let WebSocket
.- 不要
removeEventListener
。最好有一个消息处理程序,switch (message.op)
然后根据message.op
(您所命名的hello
)的值调用其他方法。 - 如果你真的想要
removeEventListener
,你不能只传递类型"message"
,你还需要传递对函数本身的引用。请参见此处和下方。 - 如果您需要保存第一条消息,即 的值
hello
,则还要将其范围限定在文件的顶层。 - 当你停止心跳时,你没有说你想做什么,但你已经有了它的位置,它就是你设置的地方
alive = false
。你可以打电话给socket.close()
那里,或者alert
你的用户出了问题。取决于您的应用程序。
const myHandler = function (data) { /* do stuff with data */ };
socket.addEventListener("message", myHandler);
socket.removeEventListener("message", myHandler);
推荐阅读
- asp.net - 如何在多对多关系中获取数据并在实体框架中返回 AsQueryable
- kubernetes - 将spring boot连接到kubernetes中的redis
- java - 如何在java中设计简单的日志分析器
- python - Python - 进入圈子
- javascript - Discord.js 错误:无法读取未定义的属性“then”
- r - rollapply 用于数据框中具有条件的某些值
- excel - 如何为每日高峰时间创建直方图?
- github - GitHub 中私有存储库的安全问题
- python - 负前瞻搜索文本中的整数
- javascript - 如何使用节点 js 将两个集合数据转换为 mongodb 中的一个输出