📜 ⬆️ ⬇️

Simple publish-subscribe for multiplayer on CoronaSDK, Gideros, Moai

Once with a colleague, we faced the problem of real-time multiplayer implementation on CoronaSDK. At first, we tried the pubnub.com service, but over time they realized that they were not satisfied with their latency (they have everything via http) and prices. Not finding anything better, we decided to quickly create our bike on Node.js (or rather a scooter, because the entire server code fits in 90 lines with comments).

Named as a joke NoobHub. Distributed under the license WTFPL.


The thing turned out to be quite fast and, judging by the feedback from users, able to spin for months on the server without restarting and memory leaks. System requirements: Node.js 0.6.x and higher (included in the standard Ubuntu package), no additional modules are required.
If you are writing a mobile multiplayer application on Lua using CoronaSDK, Moai or Gideros, then there is good news: the client for these SDKs work fine, take it and use it.
')

Some facts:



Using


Started the server:
$ node server.js
On the client created an object:
 hub = noobhub.new({ server = "127.0.0.1"; port = 1337; }); 

Subscribed to the channel, in the callback function we process the message of other participants:
 hub:subscribe({ channel = "hello-world"; callback = function(message) if(message.action == "ping") then print("Pong!") end; end; }); 

Sent a message:
  hub:publish({ message = { action = "ping", timestamp = system.getTimer() } }); 


Boring details


The key element of the Node.js script is the server object, which listens to the port and responds to connections. For each of them, a socket is created with a unique hash for later searching and deleting, if necessary.
Sockets in turn listen for data retrieval and close events.
They recognize two types of messages: __SUBSCRIBE____ENDSUBSCRIBE__ - subscription to the channel,
__JSON__START _ <_ MESSAGE> __ JSON__END__ is an arbitrary message. When subscribing, a socket is added to the CHANNELNAME pool and all subsequent messages coming through this channel will be transmitted to the newcomer. In the second case, the body MESSAGE will be addressed to all subscribers of the channel CHANNELNAME . To disconnect, it is enough to close the socket on the client side, and then the server knows what to do with the deserter.
It turns out that one EventLoop node does all the work of getting data and packaging it to clients in sockets. If there are many customers, a correspondingly increased cycle will delay the delivery of messages. The question is, of course, how many clients are needed for the drawdown to be at least somewhat noticeable. At 2k CCU, there was no drawdown of latency (we simply didn’t have more), but I doubt that 20k will give a noticeable drawdown.
On the client, everything is exactly the opposite, the client connects to the socket server, subscribes to the channel, and asynchronously listens to messages from other channel participants.
There is automatic reconnect & resubscribe when it is broken (it makes life easier for users with a bad connection on EDGE / 3G).

Total: simple Publish-Subscribe for small and even medium-sized projects.


Source code of the server and clients: https://github.com/Overtorment/NoobHub

Source: https://habr.com/ru/post/208584/


All Articles