-
Hello, I'm using uWebSockets.js along with a Protobuf protocol for a production project. It's really amazing! But is there a way to broadcast data to all currently connected clients out of the box? or the best way to do it, thanks |
Beta Was this translation helpful? Give feedback.
Replies: 17 comments
-
If uWebsocket.js doesn't collect all connections in array or set, you should do it yourself and then, by iterating through this array send message to each of stored connection. It's how broadcasting works. |
Beta Was this translation helpful? Give feedback.
-
Yes I tried that but the « ws » in the close event is just an empty object so I don’t know how to keep track and correctly remove clients when they disconnects |
Beta Was this translation helpful? Give feedback.
-
might be related: https://github.com/uNetworking/uWebSockets/issues/875 |
Beta Was this translation helpful? Give feedback.
-
Yes with pubsub we can do something like broadcasting but what if we want to keep track of connected users and when they disconnect to keep these events? |
Beta Was this translation helpful? Give feedback.
-
It's kind of weird that we can only publish by ws object, when it shouldn't be related. Publishing should be a thing of app or sth like wsManager inside app. https://github.com/uNetworking/uWebSockets.js/blob/master/examples/PubSub.js backing to question: ws should not be undefined when close event occurs, it has to be bug I guess |
Beta Was this translation helpful? Give feedback.
-
also there's currently no way to do "frame-once/send-many" (discussed somewhere in https://github.com/uNetworking/uWebSockets/issues) so the only thing we can do for now is to track active connections manually const bufferToString = buf => new Uint8Array(buf).join('.')
const getIpAddress = (res, req) => (req && req.getHeader('x-forwarded-for')) || bufferToString(res.getRemoteAddress())
const main = uws.App({})
const clients = new Set()
const idle = new Set()
main.ws('*', {
compression: 0,
maxPayloadLength: 1e6,
idleTimeout: 0,
open: (client, req) => {
client.endpoint = req.getUrl()
client.ip = getIpAddress(client, req)
clients.add(client)
},
message: (source, message) => {
clients.forEach(client => {
if (source.endpoint === client.endpoint) {
if (!client.send(message, true, false)) {
clients.delete(client)
idle.add(client)
}
}
})
},
drain: client => {
// actually it's better to check bufferedAmount here
clients.add(client)
idle.delete(client)
},
close: client => {
clients.delete(client)
idle.delete(client)
}
}) it works |
Beta Was this translation helpful? Give feedback.
-
@Kamil93 It's not undefined but look I can't call any method on this "ws" |
Beta Was this translation helpful? Give feedback.
-
@yovanoc show sth more, bit of code that displays it? |
Beta Was this translation helpful? Give feedback.
-
I've put the console.log in the second screen? what do you mean by "more code" ? |
Beta Was this translation helpful? Give feedback.
-
@yovanoc yes, you can not call any ws method, but it is same ws object you've received in .open handler. so you can track it |
Beta Was this translation helpful? Give feedback.
-
@yovanoc nvm, I saw there 1 screen, now are 2 as @dbl0null said, use for example Set object to track ws references, then you can use set.size to count them for example |
Beta Was this translation helpful? Give feedback.
-
@dbl0null Oh yes I know what you mean now, I will try that |
Beta Was this translation helpful? Give feedback.
-
@dbl0null Your custom forEach is to broadcast to all users connected to the same endpoint? |
Beta Was this translation helpful? Give feedback.
-
Just use: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach |
Beta Was this translation helpful? Give feedback.
-
drop-in replacement would be: clients.forEach(client => {
if (source.endpoint === client.endpoint) {
if (!client.send(message, true, false)) {
clients.delete(client)
idle.add(client)
}
}
}) *will update previous message |
Beta Was this translation helpful? Give feedback.
-
Broadcasting with a loop is the "bubble sort" solution, it works but is the least efficient way. The built in pub sub support, still unfinished, will be the way to go. |
Beta Was this translation helpful? Give feedback.
-
How much of a performance increase will there be? currently I do
|
Beta Was this translation helpful? Give feedback.
Broadcasting with a loop is the "bubble sort" solution, it works but is the least efficient way. The built in pub sub support, still unfinished, will be the way to go.