Roblox-Long-Polling A Node.JS Module to Make Real-Time Communication Easy [Scalable Version Now Available]

Recently I have had the need to make real-time communication from Roblox, to my own APIs, as of right now Roblox has no way to use things like websockets; because of this we have to use alternatives like Long Polling, which keeps connections alive to receive messages as soon as they occur.

The Defenition of Long Polling

Long polling is a technique where the server elects to hold a client’s connection open for as long as possible, delivering a response only after data becomes available or a timeout threshold has been reached.

Using it in Roblox
I have created an open-source Node, and Roblox module to accomplish this.

NPM Module: roblox-long-polling - npm
GitHub Module: https://github.com/ReAdminRBX/roblox-long-polling

Setting it all up

  1. Download our RobloxModule here
  2. Ensure HTTP Service is enabled as the steps below show
  3. Download the Roblox module by doing npm i roblox-long-polling
  4. Add it to your Node.JS code with the example
const rlp = require("roblox-long-polling")

const poll = new rlp({
    port: 2004, // Add this behind your IP, example: http://127.0.0.1:2004,
    //password: "passsword here" If you want to add a simple password, put uncomment this and add your password
});

poll.on('connection', (connection) => {
    console.log('New connection', connection.id);// Will fire when a new connection is active, and include this IP address.
    poll.broadcast("new connection", connection.id); // Will broadcast to all active sockets that this one has joined the part.

    connection.send('welcome', 'hello there!') // Will send a welcome message to the new socket.
    connection.on('hello', (data) => {//On a event we will handle the hello message
        console.log("received hello message!", data)
    })

    connection.on('internal_ping', () => {//We receive pings from the server to let us know its still alive, you cant disable this.
        console.log("Keep-Alive Ping received")
    })

    connection.on('dsconnect', () => { // Fired when the game sends a disconnect command, or our timeout is fired.
        console.log('Disconnection', connection.id)
        poll.broadcast("disconnection", connection.id);
    })
})
  1. Now, we’re going to install a script in ServerScriptService that requires the Module we imported earlier, this is our magic code that allows you to interface with the Node.JS API.
local robloxLongPolling = require(script.Parent.robloxLongPolling)

  

local connection = robloxLongPolling.Connect("http://72.24.217.22:2004", "")

connection:on("welcome", function(message)--This is an event fired in the above example, you can change this if you want into your own events.
print("received welcome ", message)
end)

connection:on("new connection", function(id)--This is an event fired in the above example, you can change this if you want into your own events.
print("new connection ", id)
end)

connection:on("disconnection", function(id)--Fired if we for some reason get disconnected.
print("disconnection ", id)
end)
connection:send("hello", "Hello world!")--Example on how to send messages.

wait(30)
connection:Disconnect()

Enabling HTTP Service

  1. Head on over to your game in Roblox Studio
  2. Open the top bar, and click “HOME”
  3. Click the cog named “Game Settings”
  4. In the modal that opens, click “Security”
  5. Ensure “Allow HTTP Requests” is enabled, if it isn’t, enable it.

Some Notes
Planning on releasing another version of this for scalable architecture, where a database/cache is used to keep connections open on multiple servers.

It’s open source, feel free to contribute!!!

34 Likes

Heads up for those using low-quality servers (free = often bad specifications): long polling has a performance impact. Once a long polling request is received on the server, the server keeps the thread open until a timeout or new data. Your memory consumption might grow, especially on large scale.

WebSockets, in contrary, are way more efficient. WebSockets are often used for chat applications like Discord & Skype, because of its efficiency and speed.

But, Roblox didn’t support WebSockets yet. For security reasons, this feature request has been denied by Roblox. (I just discovered at time of writing)

Anyway, this module might come great for matchmaking, real-time events, server-controlled shops and ban systems!

4 Likes

are the dependencies trusted? i only used discord.js, node-fetch, ytdl and a lot more

Yes, I am only using Express, Helmet, and UUID. Express is used to wrap the HTTP Server, Helmet protects basic vulnerabilities with Express, and UUID generates random IDs.

1 Like

This is why I am working on a scalable version that requires the use of a cache/database.

3 Likes

Out of curiosity, for a scaled version of this would you be okay with Redis being used as a pub/sub/cache for active connections?

I’ve just finished a version that allows you to use Redis to enable clustering/scalability of your APIs. Enjoy!

Docs are all here, the only change is you have to pass your redisConnection when creating the polling instance on your Javascript server.

2 Likes

This version is very much for complex users who are dealing with large amounts of servers, and data. Most people will not need to use this version.

What kind of features could developers make using this long polling system?

1 Like

It’s all up to the developer. Use cases can range from cross-server communication, such as sending chats between servers while logging them in a database, real-time APIs, and much more.

It is just WebSockets without WebSockets. It’s like RemoteEvents/Functions just connected to a server outside of Roblox. You could use it to wrap something like the Discord API [which I don’t recommend] or things like Jonas said above: matchmaking, real-time events, server-controlled shops, and ban systems.

It can do whatever you want it to do; it’s just a communication wrapper from Node.JS to Roblox. Instead of relying on one-way communication, you can communicate both ways with events.

I was asked why I made this… simply because Roblox hasn’t allowed for a client implementation of WebSockets. A Roblox employee specifically said this feature was not going to happen for security reasons a few years ago. So, it’s unlikely they will implement them any time soon. So long polling is the closest you’ll probably get to that unless they add them.

Hey There!

I’m new to JavaScript and am trying to make a console that I can use for my game from the browser, and I think this is the library I need to make it work in real-time and not on a 40 second delay or something similar. Could you please confirm that this would allow me to put commands in and have them be executed in real-time and give me an example as to how I could implement this to make a console for my game?

EDIT: Also, is there API Documentation, because it seems a little confusing.

EDIT 2: Edited the post, should be more clear now.

Uhhh what are you having problems with?

I’ve updated the post. I hope it helps.

Alright I’ve stuck the example code into a Heroku dyno but it seems to have trouble connecting. It gives me this error when I run the game:


The Heroku dyno has no errors whatsoever.

Here is a GitHub repository with all the code in it:

It’s just a Heroku dyno with the provided example code and a bit of minor changes made to it.

I’m not too sure how the Heroku platform works, it’s very possible the Heroku instance is not constantly online, which is required by this app to keep a connection open. As well as you should have to define the port on line 4 in index.js that Heroku uses.

Alright, sounds good. I’ll try that.

It is now telling me that it cannot parse the JSON:


It’s further than I was before though, so thank you!

Make sure you didn’t include a / after the website… like https://google.com/ should be https://google.com
In your module

Actually you did that, looking at your site it shows this image Might want to pull you logs and see if there was an error. Also, don’t set port 80 in your module. Just set it to https://long-polling-rb.herokuapp.com/