Difference between revisions of "Gideros Unite Framework"

From GiderosMobile
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
__NOTOC__
+
__TOC__
 
 
 
=== Gideros Unite Framework ===
 
=== Gideros Unite Framework ===
ar2rsawseen 2012/07/25 Gideros Mobile, '''updated 2023/12/13 (V2)'''
+
The Gideros Unite framework allows a host (server) and clients to connect over a Local Area Network. Some demo code:
 
 
<youtube>https://www.youtube.com/watch?v=WBFLSz34I4I</youtube>
 
 
 
Gideros Unite framework provides a way to implement Multiplayer games:
 
* using '''LuaSocket''' to establish socket connections and create '''server'''/'''client''' instances
 
* device discovery over '''L'''ocal '''A'''rea '''N'''etwork
 
* call methods on devices through the network
 
* protocols: '''tcp''', '''udp''' or both (binding some method to tcp if reliability is needed, and others to udp for faster data processing)
 
  
You can download the Gideros Unite Framework: '''[[Media:Unite.zip|Unite.zip]]'''
+
'''Get all connected devices'''
 
 
And an application project: '''[[Media:DrawTogetherV2.zip|DrawTogetherV2.zip]]'''
 
 
 
=== Standard scenario ===
 
This is a standard scenario that can be created using Gideros Unite framework:
 
# Server starts broadcasting or skip to step 5, if all clients know server IP address
 
# Client's start listening to servers
 
# Client receives broadcast message from server, newServer event is initiated
 
# Client autoconnects to server or user manually (by pushing button) connects to specific server
 
# Server receives newClient event
 
# Server accepts client automatically or user manually (by pushing button) accepts specific client
 
# Client receives onAccept event
 
# Implement your game logic here, where both clients and server can call methods on all devices or on one specific device in the network
 
# When one of the clients becomes unreachable, all clients and server get onClientClose event
 
# When server becomes unreachable, all clients get onServerClose event
 
# When you are finished, close client or server using close method, which stops all timers, closes all connections and destroys instance
 
 
 
=== Client Method list ===
 
==== Constructor ====
 
'''Method name''' new(config)
 
 
 
'''Description''' Create client instance
 
 
 
'''Input parameters''' table config - lua table with configuration options:
 
*string username - username to display on devices (default: hostname or device's IP address)
 
*string ip - ip address to use for server (default: current device's IP address)
 
*int tcpPort - port to use for tcp connection (default: 5883)
 
*int udpPort - port to use for udp connection (default: 5884)
 
*int discoveryPort - port to use for device discovery (default: 5885)
 
*int multicast - multicast ip address for device discovery (default: 239.192.1.1)
 
*int serverIP - ip address of server, if no discovery needed and can connect tp server directly (default: nil)
 
*string connectionType - which connection protocol to use tcp, udp or both (default: 'both')
 
 
 
'''Example'''
 
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
local serverlink = Client.new({
+
-- we can get all devices that are connected to our network
    username = "ar2rsawseen",
+
local devices = {}
    ip = nil,
+
serverlink:addEventListener("device", function(e)
    port = 15000,
+
print(e.data.id, e.data.ip, e.data.host)
    multicast = "239.192.1.1",
+
devices[e.data.id] = {}
    serverIP = nil,
+
devices[e.data.id].ip = e.data.ip
    connectionType = "tcp"
+
devices[e.data.id].name = e.data.host
})
+
end)
</syntaxhighlight>
 
  
==== Start Listening ====
+
serverlink:getDevices()
'''Method name''' startListening()
 
 
 
'''Description''' Start Listening to server, both when server is broadcasting/multicasting for discovery, or when client is already connected to server (for example, by providing it's ip address)
 
 
 
==== Stop Listening ====
 
'''Method name''' stopListening()
 
 
 
'''Description''' Stop Listening to server, both when server is broadcasting/multicasting for discovery, or when client is already connected to server
 
 
 
==== Connect to specified Server ====
 
'''Method name''' connect(id)
 
 
 
'''Description''' When server is broadcasting/multicasting, if client is not yet connected to any server, it recieves new server events with server ID. You need to provide that ID to connect method, to connect to specified server
 
 
 
'''Input parameters''' int id - server id received from new server event
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:connect(111222333)
 
</syntaxhighlight>
 
 
 
==== Add Method ====
 
'''Method name''' addMethod(name, method, scope)
 
 
 
'''Description''' Add method which can be called through the network by other devices
 
 
 
'''Input parameters''' Input parameters are similar to adding new event listener
 
  
string name - name of command to associate with this method, could be simply method name as string
+
-- add some methods, that could be called by other clients or server through network
 +
-- draw something
 +
serverlink:addMethod("draw", self.drawLine, self)
 +
-- end drawing
 +
serverlink:addMethod("end", self.stopDrawing, self)
 +
-- clear drawing
 +
serverlink:addMethod("clear", self.reset, self)
  
function method - method that will be called from other connected devices. This function will be called by other devices, and all parameters provided by other devices will be passed to this function. Additionally, the last providd parameter will be the source of message - id of device from which message originated
+
-- then you can call this methods when needed
 +
serverlink:callMethod("clear")
 +
serverlink:callMethod("draw", someX, someY)
  
object scope - scope to use for method, if for example using class method and not simple function, you can provide self variable if defined inside class, of class instance if defiend outside class (default: nil)
+
-- or call method of specific device using its id
 +
serverlink:callMethodOf("clear", 112233)
 +
serverlink:callMethodOf("draw", someX, someY, 112233)
  
'''Example'''
+
-- and when game is finished
<syntaxhighlight lang="lua">
 
serverlink:addMethod("draw", self.draw, self)
 
</syntaxhighlight>
 
 
 
==== Call Method ====
 
'''Method name''' callMethod(...)
 
 
 
'''Description''' Call specific method for all connected devices
 
 
 
'''Input parameters''' string command - name of command, to call the method associated with this command
 
 
 
Other parameters can be any values, that will be passed to called method
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:callMethod("draw", 100, 200)
 
</syntaxhighlight>
 
 
 
==== Call Method of specific device ====
 
'''Method name''' callMethodOf(...)
 
 
 
'''Description''' Call specific method for specific connected devices
 
 
 
'''Input parameters''' string command - name of command, to call the method associated with this command
 
 
 
Other parameters can be any values, that will be passed to called method
 
 
 
Last parameter should be the ID of device, to which to send command
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:callMethodOff("draw", 100, 200, 111222333)
 
</syntaxhighlight>
 
 
 
==== Get devices ====
 
'''Method name''' getDevices()
 
 
 
'''Description''' Get ID of all devices connected to server. Due to limitation, that ID's of devices are retrieved through sockets on the network, this method does not return list of devices, but rather generates multiple "device" events, one for each connected device
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:getDevices()
 
</syntaxhighlight>
 
 
 
==== Close Client ====
 
'''Method name''' close()
 
 
 
'''Description''' Closes the client, disconnects it from server, disabled listening and erases ID. Serves as destructor for the class
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
 
serverlink:close()
 
serverlink:close()
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Server Method list ===
+
'''Server example code'''
==== Constructor ====
 
'''Method name''' new(config)
 
 
 
'''Description''' Create server instance
 
 
 
'''Input parameters''' table config - lua table with configuration options:
 
*string username - username to display on devices (default: hostname or device's IP address)
 
*string ip - ip address to use for server (default: curret devices IP address)
 
*int tcpPort - port to use for tcp connection (default: 5883)
 
*int udpPort - port to use for udp connection (default: 5884)
 
*int discoveryPort - port to use for device discovery (default: 5885)
 
*int multicast - multicast ip address for device discovery (default: 239.192.1.1)
 
*int maxClients - maximal amount of clients server can serve (default: unlimited amount)
 
*string connectionType - which connection protocol to use tcp, udp or both (default: 'both')
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
local serverlink = Server.new({
 
    username = "IAmAServer",
 
    ip = nil,
 
    port = 15000,
 
    multicast = "239.192.1.1",
 
    maxClients = 0,
 
    connectionType = "tcp"
 
})
 
</syntaxhighlight>
 
 
 
==== Start Broadcasting ====
 
'''Method name''' startBroadcast()
 
 
 
'''Description''' Start Broadcasting to clients, both broadcast and multicast to discover other listening devices. Broadcasting includes listening, so if server is broadcasting, there is no need to call startListening method
 
 
 
==== Stop Broadcasting ====
 
'''Method name''' stopBroadcast()
 
 
 
'''Description''' Stop Broadcasting to clients
 
 
 
==== Start Listening ====
 
'''Method name''' startListening()
 
 
 
'''Description''' Start Listening to clients
 
 
 
==== Stop Listening ====
 
'''Method name''' stopListening()
 
 
 
'''Description''' Stop Listening to clients
 
 
 
==== Accept specified Client ====
 
'''Method name''' accept(id)
 
 
 
'''Description''' When client responded to broadcasting/multicasting message, server recieves new client events with client ID. You need to provide that ID to accept method, to accept specified client
 
 
 
'''Input parameters'''
 
int id - client id received from new client event
 
 
 
'''Example'''
 
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
serverlink:accept(111222333)
+
function onAccept(e)
</syntaxhighlight>
+
-- auto accept client with provided id
 +
serverlink:accept(e.data.id)
 +
end
  
==== Add Method ====
+
-- create a server instance
'''Method name''' addMethod(name, method, scope)
+
serverlink = Server.new({username = 'myServer'})
 +
-- add event to monitor when new client wants to join
 +
serverlink:addEventListener('newClient', onAccept)
 +
-- start broadcasting to discover devices
 +
serverlink:startBroadcast()
  
'''Description''' Add method which can be called through the network by other devices
+
-- and then before entering game logic
 
+
-- if we are ready to play stop broadcasting
'''Input parameters''' Input parameters are similar to adding new event listener
+
serverlink:stopBroadcast()
 
+
-- and start only listening to clients
string name - name of command to associate with this method, could be simply method name as string
+
serverlink:startListening()
 
 
function method - method that will be called from other connected devices. This function will be called by other devices, and all parameters provided by other devices will be passed to this function. Additionally, the last providd parameter will be the source of message - id of device from which message originated
 
 
 
object scope - scope to use for method, if for example using class method and not simple function, you can provide self variable if defined inside class, of class instance if defiend outside class (default: nil)
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:addMethod("draw", self.draw, self)
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== Call Method ====
+
'''Client example code'''
'''Method name''' callMethod(...)
 
 
 
'''Description''' Call specific method for all connected devices
 
 
 
'''Input parameters''' string command - name of command, to call the method associated with this command
 
 
 
Other parameters can be any values, that will be passed to called method
 
 
 
'''Example'''
 
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
serverlink:callMethod("draw", 100, 200)
+
function onJoin(e)
</syntaxhighlight>
+
-- auto connect to server with provided id
 +
serverlink:connect(e.data.id)
 +
end
  
==== Call Method of specific device ====
+
-- create client instance
'''Method name''' callMethodOf(...)
+
serverlink = Client.new({username = 'IAmAClient'})
 +
-- create event to monitor when new server starts broadcasting
 +
serverlink:addEventListener('newServer', onJoin)
  
'''Description''' Call specific method for specific connected devices
+
-- event to listen if server accepted our connection
 
+
serverlink:addEventListener('onAccepted', function()
'''Input parameters''' string command - name of command, to call the method associated with this command
+
print('server accepted our connection')
 
+
end)
Other parameters can be any values, that will be passed to called method
 
 
 
Last parameter should be the ID of device, to which to send command
 
 
 
'''Example'''
 
<syntaxhighlight lang="lua">
 
serverlink:callMethodOff("draw", 100, 200, 111222333)
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== Get devices ====
+
'''Game logic example''' (the game logic is the same for server and clients)
'''Method name''' getDevices()
 
 
 
'''Description''' Get ID of all devices connected to server. Due to limitation, that ID's of devices are retrieved through sockets on the network, this method does not return list of devices, but rather generates multiple "device" events, one for each connected device
 
 
 
'''Example'''
 
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 +
-- we can get all devices that are connected to our network
 +
local devices = {}
 +
serverlink:addEventListener('device', function(e)
 +
print(e.data.id, e.data.ip, e.data.host)
 +
devices[e.data.id] = {}
 +
devices[e.data.id].ip = e.data.ip
 +
devices[e.data.id].name = e.data.host
 +
end)
 
serverlink:getDevices()
 
serverlink:getDevices()
</syntaxhighlight>
 
  
==== Close Server ====
+
-- add some methods, that could be called by other clients or server through network
'''Method name''' close()
+
-- draw something
 +
serverlink:addMethod('draw', self.drawLine, self)
 +
-- end drawing
 +
serverlink:addMethod('end', self.stopDrawing, self)
 +
-- clear drawing
 +
serverlink:addMethod('clear', self.reset, self)
 +
 
 +
-- then you can call these methods when needed
 +
serverlink:callMethod('clear')
 +
serverlink:callMethod('draw', someX, someY)
  
'''Description''' Closes the server, disconnects all clients, disables listening and/or broadcasting and erases ID. Serves as destructor for the class
+
-- or call method of specific device using its id
 +
serverlink:callMethodOf('clear', 112233)
 +
serverlink:callMethodOf('draw', someX, someY, 112233)
  
'''Example'''
+
-- when game is finished
<syntaxhighlight lang="lua">
 
 
serverlink:close()
 
serverlink:close()
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
=== Using the Gideros Unite Framework ===
 +
ar2rsawseen 2012/07/25 Gideros Mobile, '''updated 2023/12/13 (V2)'''
  
 +
<youtube>https://www.youtube.com/watch?v=WBFLSz34I4I</youtube>
  
 +
Gideros Unite framework provides a way to implement Multiplayer games:
 +
* using LuaSocket to establish socket connections and create server/client instances
 +
* device discovery over Local Area Network
 +
* call methods on devices through the network
 +
* protocols: '''tcp''', '''udp''' or both. Binding some method to tcp if reliability is needed, and others to udp for faster data processing
  
 +
You can download the Gideros Unite Framework here: '''[[Media:Unite.zip|Unite.zip]]'''
  
=== Client Event list ===
+
And a Gideros project: '''[[Media:DrawTogetherV2.zip|DrawTogetherV2.zip]]'''
    • New Server Event
 
    • Device Event
 
    • Accept Event
 
    • Server closed Event
 
    • Another Client closed Event
 
Device Event
 
Event name
 
device
 
Description
 
Events spawned after calling getDevices method
 
Event properties
 
    • e.data.id - id of client
 
    • e.data.ip - ip address of client
 
    • e.data.host - username or hostname of client or ip if no hostname provided
 
Example input
 
1
 
2
 
3
 
4
 
5
 
serverlink:addEventListener("device", function(e)
 
    print(e.data.id)
 
    print(e.data.ip)
 
    print(e.data.host)
 
end)
 
  
Accept Event
+
=== Standard scenario ===
Event name
+
This is a standard scenario that can be created using Gideros Unite framework:
onAccepted
+
# Server starts broadcasting or skip to step 5, if all clients know server IP address
Description
+
# Client's start listening to servers
Event called when server accepted connection from this client
+
# Client receives broadcast message from server, newServer event is initiated
Example input
+
# Client autoconnects to server or user manually (by pushing button) connects to specific server
1
+
# Server receives newClient event
2
+
# Server accepts client automatically or user manually (by pushing button) accepts specific client
3
+
# Client receives onAccept event
serverlink:addEventListener("onAccepted", function(e)
+
# Implement your game logic here, where both clients and server can call methods on all devices or on one specific device in the network
    print("connection accepted")
+
# When one of the clients becomes unreachable, all clients and server get onClientClose event
end)
+
# When server becomes unreachable, all clients get onServerClose event
 
+
# When you are finished, close client or server using close method, which stops all timers, closes all connections and destroys instance
Server closed Event
 
Event name
 
onServerClose
 
Description
 
Event called when server is unreachable
 
Example input
 
1
 
2
 
3
 
serverlink:addEventListener("onServerClose", function(e)
 
    print("server closed connection")
 
end)
 
 
 
Another Client closed Event
 
Event name
 
onClientClose
 
Description
 
Event called when another client connected to the same server becomes unreachable
 
Event properties
 
    • e.data.id - id of client that disconnects
 
Example input
 
1
 
2
 
3
 
serverlink:addEventListener("onClientClose", function(e)
 
    print("client "..e.data.id.." closed connection")
 
end)
 
 
 
Server Event list
 
    • New Client Event
 
    • Device Event
 
    • Client closed connection Event
 
Device Event
 
Event name
 
device
 
Description
 
Events spawned after calling getDevices method
 
Event properties
 
    • e.data.id - id of client
 
    • e.data.ip - ip address of client
 
    • e.data.host - username or hostname of client or ip if no hostname provided
 
Example input
 
1
 
2
 
3
 
4
 
5
 
serverlink:addEventListener("device", function(e)
 
    print(e.data.id)
 
    print(e.data.ip)
 
    print(e.data.host)
 
end)
 
 
 
Client closed connection Event
 
Event name
 
onClientClose
 
Description
 
Event called when one of the clients is unreachable
 
Event properties
 
    • e.data.id - id of client
 
Example input
 
1
 
2
 
3
 
serverlink:addEventListener("onClientClose", function(e)
 
    print(e.data.id)
 
end)
 
 
 
Latest changes
 
None for now
 
About me
 
Arturs Sosins is young, but ambitious webdeveloper from Latvia.
 
Spending his days at university or work and spending evenings with his wife and little son, he still manages to find himself new challenges and contribute his work to the developer community.
 
Follow him on Twitter @ar2rsawseen or his blogs WebcodingEasy.com or AppcodingEasy.com to know what he’s up to.
 
 
 
 
 
 
 
 
 
 
 
 
 
<syntaxhighlight lang="lua">
 
</syntaxhighlight>
 
  
 +
=== Framework ===
 +
*1 [[Unite Server Method list]]
 +
*2 [[Unite Client Method list]]
 +
*3 [[Unite Server Event list]]
 +
*4 [[Unite Client Event list]]
  
'''[[Multiplayer]]'''
+
{{Unite Framework}}
{{GIDEROS IMPORTANT LINKS}}
 

Latest revision as of 08:51, 26 August 2024

Gideros Unite Framework

The Gideros Unite framework allows a host (server) and clients to connect over a Local Area Network. Some demo code:

Get all connected devices

-- we can get all devices that are connected to our network
local devices = {}
serverlink:addEventListener("device", function(e)
	print(e.data.id, e.data.ip, e.data.host)
	devices[e.data.id] = {}
	devices[e.data.id].ip = e.data.ip
	devices[e.data.id].name = e.data.host
end)

serverlink:getDevices()

-- add some methods, that could be called by other clients or server through network
-- draw something
serverlink:addMethod("draw", self.drawLine, self)
-- end drawing
serverlink:addMethod("end", self.stopDrawing, self)
-- clear drawing
serverlink:addMethod("clear", self.reset, self)

-- then you can call this methods when needed
serverlink:callMethod("clear")
serverlink:callMethod("draw", someX, someY)

-- or call method of specific device using its id
serverlink:callMethodOf("clear", 112233)
serverlink:callMethodOf("draw", someX, someY, 112233)

-- and when game is finished
serverlink:close()

Server example code

function onAccept(e)
	-- auto accept client with provided id
	serverlink:accept(e.data.id)
end

-- create a server instance
serverlink = Server.new({username = 'myServer'})
-- add event to monitor when new client wants to join
serverlink:addEventListener('newClient', onAccept)
-- start broadcasting to discover devices
serverlink:startBroadcast()

-- and then before entering game logic
-- if we are ready to play stop broadcasting
serverlink:stopBroadcast()
-- and start only listening to clients
serverlink:startListening()

Client example code

function onJoin(e)
	-- auto connect to server with provided id
	serverlink:connect(e.data.id)
end

-- create client instance
serverlink = Client.new({username = 'IAmAClient'})
-- create event to monitor when new server starts broadcasting
serverlink:addEventListener('newServer', onJoin)

-- event to listen if server accepted our connection
serverlink:addEventListener('onAccepted', function()
	print('server accepted our connection')
end)

Game logic example (the game logic is the same for server and clients)

-- we can get all devices that are connected to our network
local devices = {}
serverlink:addEventListener('device', function(e)
	print(e.data.id, e.data.ip, e.data.host)
	devices[e.data.id] = {}
	devices[e.data.id].ip = e.data.ip
	devices[e.data.id].name = e.data.host
end)
serverlink:getDevices()

-- add some methods, that could be called by other clients or server through network
-- draw something
serverlink:addMethod('draw', self.drawLine, self)
-- end drawing
serverlink:addMethod('end', self.stopDrawing, self)
-- clear drawing
serverlink:addMethod('clear', self.reset, self)

-- then you can call these methods when needed
serverlink:callMethod('clear')
serverlink:callMethod('draw', someX, someY)

-- or call method of specific device using its id
serverlink:callMethodOf('clear', 112233)
serverlink:callMethodOf('draw', someX, someY, 112233)

-- when game is finished
serverlink:close()

Using the Gideros Unite Framework

ar2rsawseen 2012/07/25 Gideros Mobile, updated 2023/12/13 (V2)

Gideros Unite framework provides a way to implement Multiplayer games:

  • using LuaSocket to establish socket connections and create server/client instances
  • device discovery over Local Area Network
  • call methods on devices through the network
  • protocols: tcp, udp or both. Binding some method to tcp if reliability is needed, and others to udp for faster data processing

You can download the Gideros Unite Framework here: Unite.zip

And a Gideros project: DrawTogetherV2.zip

Standard scenario

This is a standard scenario that can be created using Gideros Unite framework:

  1. Server starts broadcasting or skip to step 5, if all clients know server IP address
  2. Client's start listening to servers
  3. Client receives broadcast message from server, newServer event is initiated
  4. Client autoconnects to server or user manually (by pushing button) connects to specific server
  5. Server receives newClient event
  6. Server accepts client automatically or user manually (by pushing button) accepts specific client
  7. Client receives onAccept event
  8. Implement your game logic here, where both clients and server can call methods on all devices or on one specific device in the network
  9. When one of the clients becomes unreachable, all clients and server get onClientClose event
  10. When server becomes unreachable, all clients get onServerClose event
  11. When you are finished, close client or server using close method, which stops all timers, closes all connections and destroys instance

Framework