How Can I Use MessagingService?

Hello! :wave:

I’ve been wondering how to use messaging service, so how do I use it? I don’t understand any videos, dev forum topics and the dev hub regarding this topic. Bye! :wave:

Well, Messaging Service is a way to send a signal from one server to every server in a game!

You would send the data with something like this!


game.ReplicatedStorage.Message:Connect(function(plr, txt) --gets the player and what ever data you want to send from a remotefunction, the remote function can be replaced with any other form of getting data!
local message = {Text = txt} 
game:GetService("MessagingService"):PublishAsync("GlobalAnnouncement", message) --this sends the text!

Then you will need another script to receive that message!

game.Players.PlayerAdded:Connect(function(plr) -- finds the player
	game:GetService("MessagingService"):SubscribeAsync("GlobalAnnouncement", function(message) -- gets the message
	print(message.Data.Text) -- prints the Text, remember to write message.Data before defining the data you want!
	end)
end)

There! You’ve sent a message from one server to every server!

1 Like

You probably don’t want to do SubscribeAsync inside of PlayerAdded in this scenario. You should probably use SubscribeAsync once and iterate over the players within the function.

I have a weird MessagingService handler which works by only having one SubscribeAsync call which is connected once, and then you can :Connect() to it every time, it’s very OOP based.

I don’t even know if SubscribeAsync is even already optimized this way, but yeah.

Just felt like sharing this code because I made it and woudn’t do anything with it anyway.
(You’ll need to have a Signal API under this if you were to use this)

local MessagingService = game:GetService("MessagingService");
local HttpService = game:GetService("HttpService");

local Signal = require(script:WaitForChild("Signal"))
--\\ Services and APIs: ^

--// Internal Signals;
local MESSAGER_LOADED = Signal.new();
local LOADED_MESSAGERS = {};

--
local Service = {};
Service.__index = Service;
Service.ClassName = 'MultiServerService';

--// Specific-event handlers.
local EVENT_HANDLERS = {
    PlayerKick = function(...)
        local args = table.pack(...);

        local plr = game.Players:GetPlayerByUserId(args[1])
        local kickMessage = args[2] or "\n\nYou have been kicked!\n\n"
        if not plr then return end

        plr:Kick(kickMessage);
    end;
};

--// Private functions:

local function getRandomBoolean()
    local y = math.random(1, 2)
    if y == 1 then
        return false
    else
        return true
    end
end

--

function Service:GetMessagerAsync(topicName: string)
    assert(self:IsA('MultiServerService'), ':GetMessagerAsync() is only available for the service.')

    if LOADED_MESSAGERS[topicName] == "loading" then
        return self:WaitForMessagerLoaded(topicName);
    end
    --\\ Handles current-loading messagers.

    LOADED_MESSAGERS[topicName] = "loading";

    local messager = setmetatable({
        ClassName = 'Messager';
        _topic = topicName;
        _signal = Signal.new();
        _confirmNeeded = {};
    }, Service)

    local sucess, errorMsg;

    while true do
        sucess, errorMsg = pcall(MessagingService.SubscribeAsync, MessagingService, topicName, function(info)
            local args = info.Data

            local specificHandler = EVENT_HANDLERS[args[1]]
            if specificHandler then
                table.remove(args, 1)
                return specificHandler(table.unpack(args))
            end
            --\\ Specific action handling, like :KickPlayerAsync();

            table.remove(args, 1) --\\ Remove request data.
            messager._signal:Fire(table.unpack(args))
        end)

        if sucess then break end
        
        warn('[MultiServerService Loading Error]:', errorMsg)
        wait(2);
    end
    
    LOADED_MESSAGERS[topicName] = messager;
    MESSAGER_LOADED:Fire(messager, topicName);
    return messager;
end

function Service:WaitForMessagerLoaded(topicName: string)
    assert(self:IsA('MultiServerService'), ':WaitForMessagerLoaded() is only available for the service.')


    if LOADED_MESSAGERS[topicName] ~= "loading" then
        if LOADED_MESSAGERS[topicName] then return LOADED_MESSAGERS[topicName] end
    end

    --\\ If there's no messager loading!
    while true do
        local messager, messagerName = MESSAGER_LOADED:Wait()

        if messagerName == topicName then
            return messager
        end
    end
end

function Service:IsA(...)
    return ... == self.ClassName;
end

function Service:Connect(...)
    assert(self:IsA('Messager'), ':Connect() is only meant for Messagers!')

    return self._signal:Connect(...)
end

function Service:SendAsync(...)
    assert(self:IsA('Messager'), ':SendAsync() is only meant for Messagers!')
    
    local sucess, errorMsg;
    local tries = 0;
    while true do
        sucess, errorMsg = pcall(MessagingService.PublishAsync, MessagingService, self._topic, table.pack('NormalRequest', ...))

        if sucess then return sucess end

        if not sucess then
            tries += 1
            warn('[MultiServerService Retry Error]:', errorMsg)
        end

        if tries >= 5 then return error(":SendAsync() failed after 5 attempts! It's either down, or you're sending data incorrectly!") end
        wait(1);
    end
end

function Service:KickPlayerAsync(userId: number, kickMessage: string?)
    assert(self:IsA('Messager'), ':KickPlayerAsync() is only meant for Messagers!')
    
    local sucess, errorMsg;
    local tries = 0;

    while true do
        sucess, errorMsg = pcall(MessagingService.PublishAsync, MessagingService, self._topic, {'PlayerKick', userId, kickMessage})

        if sucess then return sucess end

        if not sucess then
            tries += 1
            warn('[MultiServerService Retry Error]:', errorMsg)
        end

        if tries >= 5 then return error(":KickPlayerAsync() failed after 5 attempts!") end
        wait(1);
    end
end

--
return setmetatable(Service, Service)

I am aware of this, just wanted to make a simple intro to messaging service.

1 Like

Oh, so with the function PublishAsync, you send a message to all the servers. Then with SubscribeAsync, you retrieve that message? And the function inside of SubscribeAsync, what does it do?

I believe that would be the data that its receiving!

So the function inside subscribeasync will be the data that is sent?

1 Like

function(message) - the word message is the data its retrieving

1 Like

it is important to note that (message) is a string that holds the data. so to access the specific data you need to do:

message.Data.DATANAMEHERE

1 Like