Messaging Service

Introduction

Recently Roblox released a new service called MessagingService, this allows for you to easily communicate between all of your running servers. How is this useful? Users can do so many things now that before were extremely complex and typically required an external webhost/database, things like custom matchmaking and crossover chats.

In this tutorial I will be teaching you how to use MessagingService to create a crossover chat. I will be releasing a tutorial in the near future about how you can make your own cross server matchmaking using MessagingService

Disclaimer This is a new service so there is always the off chance that something may not function properly or will be changed in the future!

Functions

  • PublishAsync(key, data) sends out data to be received by all other servers.
  • SubscribeAsync(key, callback) receives data on all servers

Example
Cross Server Chat

So, how do we create our cross server chat? Let me start off by saying that this is not a UI Tutorial or a Custom Chat system tutorial, this is strictly a basic example on how to communicate between servers. If you are looking for a UI tutorial then I would suggest reading @EmeraldSlash’s

The first thing we need to do is detect when the player chats, to do that we can use Chatted

local Players = game:GetService("Players") -- Player Service in order to detect when a user joins

Players.PlayerAdded:connect(function(player) -- Detecting when a player joins
   player.Chatted:connect(function(msg) -- Detecting when a message is send
      -- When a user chats whatever is inside of here will be called
   end)
end)

There we go! A basic chat detection but you most likely already knew about that, so lets get in to the juicy stuff! Sending out data for every server to read is very simple all you need to do is PublishAsync your data, however tables nor objects can be sent between two servers, this means we’ll need to encode our table before sending it off. We can use JSONEncode

So first we need to create our table that will contain what our message says as well as the user who sent it.

local messageData = {
   sender = player,
   message = msg,
}

There we go! Now we have our table. Be sure to filter the message sent though!
Now we need to encode our table and send it out to all of the servers, simple enough right?

local httpService = game;GetService("HTTPService")

local encoded = httpService:JSONEncode(messageData)

Just like that our data has been encoded and it’s ready to be sent out! So lets do that now by using PublishAsync. Now don’t forget that it requires a key before our data that we’re sending, we’ll use “Chat” for our key.

local messagingService = game:GetService("MessagingService")

messagingService:PublishAsync("Chat", encoded)

And just like that half of our code is already done, great! We’ll now need to catch all of our sent data, we’ll use SubscribeAsync for that. It requires our key as well as a callback function.

function callbackFunction(serviceData)

end)

messagingService:SubscribeAsync("Chat", callbackFunction)

serviceData in our callback function is actually a table containing two values data and sent, Data being what we sent and Sent being the tick in which the request was made.
Now lets finish the system up and send out our chat message!

local decodedData = httpService:JSONDecode(serviceData.data)

print(decodedData.sender.." : "..decodedData.message)

With all of this information you could do so much more then what I’m showing, but this is just a basic rundown! I hope you learned something and now have a general understanding of how to use this service, if you don’t then please ask questions!

Finished Product

local Players = game:GetService("Players")
local httpService = game:GetService("HttpService")
local messagingService = game:GetService("MessagingService")

function callbackFunction(serviceData)
   local decodedData = httpService:JSONDecode(serviceData.data)

   print(decodedData.sender.." : "..decodedData.message)
end)

Players.PlayerAdded:connect(function(player)
   player.Chatted:connect(function(msg) 
      local messageData = {
         sender = player,
         message = msg, -- filter message first!
      }
      local encoded = httpService:JSONEncode(messageData)
      messagingService:PublishAsync("Chat", encoded)
   end)
end)

messagingService:SubscribeAsync("Chat", callbackFunction)
103 Likes

But, player is an object and by serializing it won’t save that. So this wouldn’t work, as sender should be player.Name not player.

4 Likes

You’re 100% right! Apologies

1 Like

Your code doesn’t work it has a few errors.

You don’t need to use JSON Encode and Decode, it’s automatically done for you by the Service, this also applies for DataStoreService so all you are doing is just double Encoding.


This also applies for Bindable/Remote Instances and DataStoreService.

As a result when I send this {plr.Name,msg,["John"] = true} a Mixed-Table as a message John doesn’t exist on the other end.

Working Code
	local PlayerS = game:GetService("Players")
	local HttpService = game:GetService("HttpService")
	local MessagingS = game:GetService("MessagingService")
	
	function SubscribeAsync_Func(Data)
		for i,v in pairs(Data) do
			print(i,v)
			print(typeof(i),typeof(v))
			if typeof(i) == 'table' then
				print('		i',i,"Table")
				for ii,vv in pairs(i) do
					print('			',ii,vv)
				end
			elseif typeof(v) == 'table' then
				print('		v',v,"Table")
				for ii,vv in pairs(v) do
					print('			',ii,vv)
				end
			end
		end
	--	JSONDecode
	--	print(HttpService:JSONDecode(Data.Data))
	--	print(typeof(HttpService:JSONDecode(Data.Data)))
	--	print(unpack(HttpService:JSONDecode(Data.Data)))
	end
	
	PlayerS.PlayerAdded:Connect(function(plr)
		plr.Chatted:Connect(function(msg) 
			MessagingS:PublishAsync("Chat",{PlayerName = plr.Name,Message = msg}) -- {plr.Name,msg,["John"] = true} -- HttpService:JSONEncode({plr.Name,msg})
		end)
	end)
	
	MessagingS:SubscribeAsync("Chat", SubscribeAsync_Func)

Output;

image

This is what the Data you get from SubscribeAsync looks like.

It’s a Dictionary containing Sent time and Data you passed to PublishAsync

Here’s what it looks like;

local SubscribeAsync_Data = {
	Data = {}, -- Data you pass to PublishAsync, (Variant)
	Sent = os.time() -- Time Sent, (Number)
}

The only problem that I have is the 1kB limit. How am I suppose to know how big the data I’m sending is?

12 Likes

yes we dont know how big the data , this not a problem just with this even remote events have limits and we have no way of checking the size of the data we are sending

That’s my bad, this wasn’t a feature when I made this document before the official wiki page got made.

Assuming 1kB is 1000 bytes, each character sent is 1 byte, and the limit only affects the data, you could probably send, at most, 1000 characters per message.

Perhaps you could check if the message is bigger than 1000 (or so) characters?

You should probably add FilterStringForBroadcast so you aren’t breaking the TOS with this script.

is it just for me, or have they removed the data size limit?
image

I can’t find anything about a data limit, look for yourself

I still see this right on the wiki?

@CoreDev

message = msg, -- filter message first!

I meant the 1kb size limit? 30 char limit

Ah, I didn’t see that there. Thanks for pointing it out, though you still should filter it in the example.

1 Like

Hello,

local decodedData = httpService:JSONDecode(serviceData.data)

Just thought you should know that it’s Data not data.
I was coming across a few errors, this was why.

Thanks!
(Could be wrong, this is the first time I’ve used MessagingService.)

1 Like

Hey there! :wave:

I didn’t see anything for bubble chat, does this support bubble chat or?

MessagingService has nothing to do with bubble chat…??

3 Likes