Increase server to client com message limit.
Long sscsm com messages are now split over multiple chat messages.
This commit is contained in:
parent
b2b23654d4
commit
7ed12d0419
|
@ -83,7 +83,8 @@ change in a future release.
|
|||
- `sscsm.com_send(player_or_name, channel, msg)`: Sends `msg`
|
||||
(a JSON-compatible object) to `player_or_name` on the SSCSM com channel
|
||||
`channel`. Channel names should be `modname` or `modname:name` to prevent
|
||||
conflicts.
|
||||
conflicts. *Although the limit for server-to-client messages is 128MB, I
|
||||
strongly recommend not sending large messages when not necessary.*
|
||||
- `sscsm.com_send_all(channel, msg)`: Sends `msg` to all clients that are
|
||||
running SSCSMs.
|
||||
- `sscsm.register_on_com_receive(channel, function(name, msg))`: Registers a
|
||||
|
|
33
init.lua
33
init.lua
|
@ -202,6 +202,7 @@ local function validate_channel(channel)
|
|||
end
|
||||
end
|
||||
|
||||
local msgids = {}
|
||||
function sscsm.com_send(pname, channel, msg)
|
||||
if minetest.is_player(pname) then
|
||||
pname = pname:get_player_name()
|
||||
|
@ -212,8 +213,34 @@ function sscsm.com_send(pname, channel, msg)
|
|||
else
|
||||
msg = assert(minetest.write_json(msg))
|
||||
end
|
||||
minetest.chat_send_player(pname, '\001SSCSM_COM\001' .. channel .. '\001'
|
||||
.. msg)
|
||||
|
||||
-- Short messages can be sent all at once
|
||||
local prefix = '\001SSCSM_COM\001' .. channel .. '\001'
|
||||
if #msg < 65300 then
|
||||
minetest.chat_send_player(pname, prefix .. msg)
|
||||
return
|
||||
end
|
||||
|
||||
-- You should never send messages over 128MB to clients
|
||||
assert(#msg < 134217728)
|
||||
|
||||
-- Otherwise split the message into multiple chunks
|
||||
prefix = prefix .. '\001'
|
||||
local id = #msgids + 1
|
||||
local i = 0
|
||||
msgids[id] = true
|
||||
local total_msgs = math.ceil(#msg / 65000)
|
||||
repeat
|
||||
i = i + 1
|
||||
minetest.chat_send_player(pname, prefix .. id .. '\001' .. i ..
|
||||
'\001' .. total_msgs .. '\001' .. msg:sub(1, 65000))
|
||||
msg = msg:sub(65001)
|
||||
until msg == ""
|
||||
|
||||
-- Allow the ID to be reused on the next globalstep.
|
||||
minetest.after(0, function()
|
||||
msgids[id] = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local registered_on_receive = {}
|
||||
|
@ -272,7 +299,7 @@ function sscsm.com_send_all(channel, msg)
|
|||
end
|
||||
|
||||
-- Testing
|
||||
minetest.after(1, function()
|
||||
minetest.after(0, function()
|
||||
-- Check if any other SSCSMs have been registered.
|
||||
local c = 0
|
||||
for k, v in pairs(sscsm.registered_csms) do
|
||||
|
|
|
@ -212,6 +212,30 @@ function sscsm.register_on_com_receive(channel, func)
|
|||
table.insert(registered_on_receive[channel], func)
|
||||
end
|
||||
|
||||
-- Load split messages
|
||||
local incoming_messages = {}
|
||||
local function load_split_message(chan, msg)
|
||||
print('Got split message chunk')
|
||||
local id, i, l, pkt = msg:match('^\1([^\1]+)\1([^\1]+)\1([^\1]+)\1(.*)$')
|
||||
id, i, l = tonumber(id), tonumber(i), tonumber(l)
|
||||
|
||||
if not incoming_messages[id] then
|
||||
incoming_messages[id] = {}
|
||||
end
|
||||
local msgs = incoming_messages[id]
|
||||
msgs[i] = pkt
|
||||
|
||||
-- Return true if all the messages have been received
|
||||
if #msgs < l then return end
|
||||
for i = 1, l do
|
||||
if not msgs[i] then
|
||||
return
|
||||
end
|
||||
end
|
||||
incoming_messages[id] = nil
|
||||
return table.concat(msgs, '')
|
||||
end
|
||||
|
||||
-- Detect messages and handle them
|
||||
minetest.register_on_receiving_chat_message(function(message)
|
||||
local chan, msg = message:match('^\001SSCSM_COM\001([^\001]*)\001(.*)$')
|
||||
|
@ -222,7 +246,16 @@ minetest.register_on_receiving_chat_message(function(message)
|
|||
if not callbacks then return end
|
||||
|
||||
-- Load the message
|
||||
if msg:sub(1, 1) == '\002' then
|
||||
local prefix = msg:sub(1, 1)
|
||||
if prefix == '\001' then
|
||||
msg = load_split_message(chan, msg)
|
||||
if not msg then
|
||||
return true
|
||||
end
|
||||
prefix = msg:sub(1, 1)
|
||||
end
|
||||
|
||||
if prefix == '\002' then
|
||||
msg = msg:sub(2)
|
||||
else
|
||||
msg = minetest.parse_json(msg)
|
||||
|
@ -230,7 +263,10 @@ minetest.register_on_receiving_chat_message(function(message)
|
|||
|
||||
-- Run callbacks
|
||||
for _, func in ipairs(callbacks) do
|
||||
func(msg)
|
||||
local ok, msg = pcall(func, msg)
|
||||
if not ok then
|
||||
minetest.log('error', '[SSCSM] ' .. tostring(msg))
|
||||
end
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
|
|
@ -89,6 +89,10 @@ sscsm.every(60, function(param1)
|
|||
end, 123)
|
||||
|
||||
sscsm.register_on_com_receive('sscsm:testing', function(msg)
|
||||
print('Got ' .. minetest.serialize(msg):sub(8) .. ' from the server')
|
||||
sscsm.com_send('sscsm:testing', msg)
|
||||
if #msg > 400 then
|
||||
print('Got large message of length ' .. #msg .. ' from the server')
|
||||
else
|
||||
sscsm.com_send('sscsm:testing', msg)
|
||||
print('Got ' .. minetest.serialize(msg):sub(8) .. ' from the server')
|
||||
end
|
||||
end)
|
||||
|
|
Loading…
Reference in New Issue