81064cc239
We don't use that info for anything, and it generates unnecessary diffs every time we bump the minor version (and CI failures if we forget to sync some files from opt-in modules (mono, text_server_fb).
178 lines
6.6 KiB
XML
178 lines
6.6 KiB
XML
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<class name="UDPServer" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
|
<brief_description>
|
|
Helper class to implement a UDP server.
|
|
</brief_description>
|
|
<description>
|
|
A simple server that opens a UDP socket and returns connected [PacketPeerUDP] upon receiving new packets. See also [method PacketPeerUDP.connect_to_host].
|
|
After starting the server ([method listen]), you will need to [method poll] it at regular intervals (e.g. inside [method Node._process]) for it to process new packets, delivering them to the appropriate [PacketPeerUDP], and taking new connections.
|
|
Below a small example of how it can be used:
|
|
[codeblocks]
|
|
[gdscript]
|
|
# server_node.gd
|
|
class_name ServerNode
|
|
extends Node
|
|
|
|
var server := UDPServer.new()
|
|
var peers = []
|
|
|
|
func _ready():
|
|
server.listen(4242)
|
|
|
|
func _process(delta):
|
|
server.poll() # Important!
|
|
if server.is_connection_available():
|
|
var peer: PacketPeerUDP = server.take_connection()
|
|
var packet = peer.get_packet()
|
|
print("Accepted peer: %s:%s" % [peer.get_packet_ip(), peer.get_packet_port()])
|
|
print("Received data: %s" % [packet.get_string_from_utf8()])
|
|
# Reply so it knows we received the message.
|
|
peer.put_packet(packet)
|
|
# Keep a reference so we can keep contacting the remote peer.
|
|
peers.append(peer)
|
|
|
|
for i in range(0, peers.size()):
|
|
pass # Do something with the connected peers.
|
|
[/gdscript]
|
|
[csharp]
|
|
// ServerNode.cs
|
|
using Godot;
|
|
using System.Collections.Generic;
|
|
|
|
public partial class ServerNode : Node
|
|
{
|
|
private UdpServer _server = new UdpServer();
|
|
private List<PacketPeerUdp> _peers = new List<PacketPeerUdp>();
|
|
|
|
public override void _Ready()
|
|
{
|
|
_server.Listen(4242);
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
_server.Poll(); // Important!
|
|
if (_server.IsConnectionAvailable())
|
|
{
|
|
PacketPeerUdp peer = _server.TakeConnection();
|
|
byte[] packet = peer.GetPacket();
|
|
GD.Print($"Accepted Peer: {peer.GetPacketIP()}:{peer.GetPacketPort()}");
|
|
GD.Print($"Received Data: {packet.GetStringFromUtf8()}");
|
|
// Reply so it knows we received the message.
|
|
peer.PutPacket(packet);
|
|
// Keep a reference so we can keep contacting the remote peer.
|
|
_peers.Add(peer);
|
|
}
|
|
foreach (var peer in _peers)
|
|
{
|
|
// Do something with the peers.
|
|
}
|
|
}
|
|
}
|
|
[/csharp]
|
|
[/codeblocks]
|
|
[codeblocks]
|
|
[gdscript]
|
|
# client_node.gd
|
|
class_name ClientNode
|
|
extends Node
|
|
|
|
var udp := PacketPeerUDP.new()
|
|
var connected = false
|
|
|
|
func _ready():
|
|
udp.connect_to_host("127.0.0.1", 4242)
|
|
|
|
func _process(delta):
|
|
if !connected:
|
|
# Try to contact server
|
|
udp.put_packet("The answer is... 42!".to_utf8_buffer())
|
|
if udp.get_available_packet_count() > 0:
|
|
print("Connected: %s" % udp.get_packet().get_string_from_utf8())
|
|
connected = true
|
|
[/gdscript]
|
|
[csharp]
|
|
// ClientNode.cs
|
|
using Godot;
|
|
|
|
public partial class ClientNode : Node
|
|
{
|
|
private PacketPeerUdp _udp = new PacketPeerUdp();
|
|
private bool _connected = false;
|
|
|
|
public override void _Ready()
|
|
{
|
|
_udp.ConnectToHost("127.0.0.1", 4242);
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
if (!_connected)
|
|
{
|
|
// Try to contact server
|
|
_udp.PutPacket("The Answer Is..42!".ToUtf8Buffer());
|
|
}
|
|
if (_udp.GetAvailablePacketCount() > 0)
|
|
{
|
|
GD.Print($"Connected: {_udp.GetPacket().GetStringFromUtf8()}");
|
|
_connected = true;
|
|
}
|
|
}
|
|
}
|
|
[/csharp]
|
|
[/codeblocks]
|
|
</description>
|
|
<tutorials>
|
|
</tutorials>
|
|
<methods>
|
|
<method name="get_local_port" qualifiers="const">
|
|
<return type="int" />
|
|
<description>
|
|
Returns the local port this server is listening to.
|
|
</description>
|
|
</method>
|
|
<method name="is_connection_available" qualifiers="const">
|
|
<return type="bool" />
|
|
<description>
|
|
Returns [code]true[/code] if a packet with a new address/port combination was received on the socket.
|
|
</description>
|
|
</method>
|
|
<method name="is_listening" qualifiers="const">
|
|
<return type="bool" />
|
|
<description>
|
|
Returns [code]true[/code] if the socket is open and listening on a port.
|
|
</description>
|
|
</method>
|
|
<method name="listen">
|
|
<return type="int" enum="Error" />
|
|
<param index="0" name="port" type="int" />
|
|
<param index="1" name="bind_address" type="String" default=""*"" />
|
|
<description>
|
|
Starts the server by opening a UDP socket listening on the given [param port]. You can optionally specify a [param bind_address] to only listen for packets sent to that address. See also [method PacketPeerUDP.bind].
|
|
</description>
|
|
</method>
|
|
<method name="poll">
|
|
<return type="int" enum="Error" />
|
|
<description>
|
|
Call this method at regular intervals (e.g. inside [method Node._process]) to process new packets. And packet from known address/port pair will be delivered to the appropriate [PacketPeerUDP], any packet received from an unknown address/port pair will be added as a pending connection (see [method is_connection_available], [method take_connection]). The maximum number of pending connection is defined via [member max_pending_connections].
|
|
</description>
|
|
</method>
|
|
<method name="stop">
|
|
<return type="void" />
|
|
<description>
|
|
Stops the server, closing the UDP socket if open. Will close all connected [PacketPeerUDP] accepted via [method take_connection] (remote peers will not be notified).
|
|
</description>
|
|
</method>
|
|
<method name="take_connection">
|
|
<return type="PacketPeerUDP" />
|
|
<description>
|
|
Returns the first pending connection (connected to the appropriate address/port). Will return [code]null[/code] if no new connection is available. See also [method is_connection_available], [method PacketPeerUDP.connect_to_host].
|
|
</description>
|
|
</method>
|
|
</methods>
|
|
<members>
|
|
<member name="max_pending_connections" type="int" setter="set_max_pending_connections" getter="get_max_pending_connections" default="16">
|
|
Define the maximum number of pending connections, during [method poll], any new pending connection exceeding that value will be automatically dropped. Setting this value to [code]0[/code] effectively prevents any new pending connection to be accepted (e.g. when all your players have connected).
|
|
</member>
|
|
</members>
|
|
</class>
|