-
Notifications
You must be signed in to change notification settings - Fork 2
Home
Neteria will allow you to discover Neteria Servers, register with those servers, and send serialized data to and from the server. With it, you can easily send python data (such as dictionaries, lists, etc.) over the network for game networking.
Contents
In order to communicate with the server, the client will first need to register with the server. Registering allows us to keep track of everyone the server is communicating with. An easy way to register with a server is using Neteria's autodiscover method. Autodiscover will send a UDP broadcast on Neteria's default port and automatically register to the first server that responds.
# Import the client
from neteria.client import NeteriaClient
class Game():
def __init__(self):
self.client = NeteriaClient(self)
self.client.autodiscover(autoregister=True)
Alternatively, you can manually register to a specific IP address using the Neteria client's register method:
register_info = ("192.168.0.5", 10858)
self.client.register(register_info)
Once the client is registered with the server, you can easily send network events to the server using the Neteria client "event" method. You can send any type of normal python data type (e.g. dict, string, list, etc.). Here's how you could send a network event to the server:
event_data = {"KEYDOWN": "up"}
self.client.event(event_data)
In the Neteria Networking client/server model, the server inherently will never trust the client. Each network event that the server receives from a client must pass through a "middleware" that judges the legality of the event. If the event is LEGAL, then it will respond to the client saying that the event was legal and it will process the event data accordingly. If the event was ILLEGAL, it will respond to the client saying the event was not legal and the client will appropriately roll back the changes.
Now any events still processing on the server will be appended to NeteriaClient.event_uuids and any events that were deemed illegal by the server will be added to the Neteria.event_rollbacks dictionary. This allows you to handle illegal events on the client side however you want.
The Neteria server will automatically handle client registration and client/server events. Any events that the server receives will be sent to a custom-defined middleware that will judge the legality of the client event. If an event is legal, it's up to your middleware to set the appropriate game variables and/or run functions in response to the event. A very simple middleware would be one which will automatically return "LEGAL" to all client network events.
Here's the simplest example of using Neteria server with middleware:
from neteria.server import NeteriaServer
from neteria.tools import _Middleware
class GameServer(object):
def __init__(self):
middleware = _Middleware(self)
self.server = NeteriaServer(middleware)
If the server needs to send data to the client without prompt from the client (e.g. another player's position changes), it will send a NOTIFY message to all the clients with the appropriate event data.
client_id = "1234"
event_data = {"HEALTH": 40}
NeteriaServer.notify(client_id, event_data)
Neteria networking uses a simple UDP JSON API to communicate between client and server. If you wish to develop your own Neteria client that can communicate with a Neteria server, you can use the following API to do so.
To discover Neteria servers on the local network, you can send an autodiscover request to the broadcast address and listen for responses. The response will let you know the IP and port to contact the Neteria server on.
Property | Type | Description |
---|---|---|
method | string | The method of the request. Should be set to "OHAI". |
cuuid | string | The client's universally unique identifier. |
version | string | A string of the client version number. This can be used on the server side to process requests differently for different client versions. |
Example
{"method": "OHAI", "cuuid": "adca9750-67e3-11e4-9803-0800200c9a66", "version": "1.0"}
The server will respond with its version. You can then use the request's originating address to determine the server's address to send a subsequent register request.
Example
{"method": "OHAI Client", "version": "1.0"}
All Neteria clients must be registered to a server before they can start sending events. To register with an Neteria server, send the following JSON request:
Property | Type | Description |
---|---|---|
method | string | The method of the request. Should be set to "REGISTER". |
cuuid | string | The client's universally unique identifier. |
version | string | A string of the client version number. This can be used on the server side to process requests differently for different client versions. |
Example
{"method": "REGISTER", "cuuid": "adca9750-67e3-11e4-9803-0800200c9a66", "version": "1.0"}
Success:
{"method": "OK REGISTER"}
Failure:
{"method": "BYE REGISTER"}
After the client has successfully registered with the Neteria server, you can send events to it. Since the client is inherently not trusted by the server, all event requests are sent to the Neteria server's judiciary "middleware" to determine if the event is LEGAL or not.
Property | Type | Description |
---|---|---|
method | string | The method of the request. Should be set to "EVENT". |
cuuid | string | The client's universally unique identifier. |
euuid | string | The event's universally unique identifier. Each event should have an event ID associated with it so it can be kept track of locally. |
event_data | any | The arbitrary event data that you wish to send to the server. This data will be passed through the server's judicial middleware to determine if the event was legal or not. |
timestamp | string | A string of the datetime.datetime.now(). |
retry | integer | The current retry attempt. |
priority | string | Whether or not the client should wait for a legality response from the server before executing its event locally. A "normal" priority event should wait for a response, whereas a "high" priority event should not wait for the server, but rollback or correct its action if the event was declared "ILLEGAL" by the server. |
Example
{"method": "EVENT",
"cuuid": "adca9750-67e3-11e4-9803-0800200c9a66",
"euuid": "2377d640-67e7-11e4-9803-0800200c9a66",
"event_data": {"KDOWN": "UP"},
"timestamp": "2014-11-09 00:06:37.011000",
"retry": 0,
"priority": "normal"}
Legal:
{"method": "LEGAL", "euuid": "2377d640-67e7-11e4-9803-0800200c9a66", "priority": "normal"}
Illegal:
{"method": "ILLEGAL", "euuid": "2377d640-67e7-11e4-9803-0800200c9a66", "priority": "normal"}
Not registered:
{"method": "BYE EVENT", "data": "Not registered"}
After receiving a "LEGAL" or "ILLEGAL" response from the server, you must send back a "OK EVENT" confirmation message indicating that the client received the response.
Example
{"cuuid": "adca9750-67e3-11e4-9803-0800200c9a66", "method": "OK EVENT", "euuid": "2377d640-67e7-11e4-9803-0800200c9a66"}
When a client is registered, it may receive a message with the "NOTIFY" method from the server. A "NOTIFY" method is identical to the "EVENT" method, except it is only used to send data from the server to the client. Since all messages that come from the server are LAW, there is no need to pass "NOTIFY" messages through a judiciary middleware.
{"method": "NOTIFY", "event_data": {"YOU ARE DEAD": True}, "euuid": "7f1d43b0-67ea-11e4-9803-0800200c9a66"}
After receiving a "NOTIFY" message from the server, you must send back a "OK NOTIFY" confirmation message indicating that the client received the response.
Example
{"method": "OK NOTIFY", "euuid": "7f1d43b0-67ea-11e4-9803-0800200c9a66", "cuuid": "adca9750-67e3-11e4-9803-0800200c9a66"}
Here is a diagram detailing how the Neteria server and client communicate with each other: