diff --git a/ClientServerLib/AndroidRemote/AndroidRemote.csproj b/ClientServerLib/AndroidRemote/AndroidRemote.csproj
index a5f49241..91c8cc78 100644
--- a/ClientServerLib/AndroidRemote/AndroidRemote.csproj
+++ b/ClientServerLib/AndroidRemote/AndroidRemote.csproj
@@ -76,6 +76,9 @@
ClientServerLib\Vocaluxe\VocaluxeStructs.cs
+
+ ClientServerLib\CDiscover.cs
+
diff --git a/ClientServerLib/ClientServerLib/CDiscover.cs b/ClientServerLib/ClientServerLib/CDiscover.cs
new file mode 100644
index 00000000..2242cf92
--- /dev/null
+++ b/ClientServerLib/ClientServerLib/CDiscover.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Timers;
+
+namespace ClientServerLib
+{
+ public delegate void OnServerDiscovered(string IPAddress, string Hostname);
+
+ public class CDiscover
+ {
+ private string _Keyword;
+ private string _BroadcastAddress;
+ private int _Port;
+
+ private Thread _DiscoverThread;
+ private bool _DiscoverRunning;
+ private OnServerDiscovered _OnDiscovered;
+
+
+ private System.Timers.Timer _BroadcastTimer;
+
+ public CDiscover(int Port, string Keyword, string BroadcastAddress = "255.255.255.255")
+ {
+ _BroadcastAddress = BroadcastAddress;
+ _Port = Port;
+ _Keyword = Keyword;
+
+ _DiscoverRunning = false;
+ _BroadcastTimer = new System.Timers.Timer();
+ _BroadcastTimer.Elapsed += new ElapsedEventHandler(OnBroadcastEvent);
+ _BroadcastTimer.Interval = 2500;
+ }
+
+ public void StartBroadcasting()
+ {
+ _BroadcastTimer.Start();
+ }
+
+ public void Stop()
+ {
+ _BroadcastTimer.Stop();
+ _DiscoverRunning = false;
+ }
+
+ public void Discover(OnServerDiscovered OnDiscovered, int Timeout = 5000)
+ {
+ if (_DiscoverRunning)
+ return;
+
+ _DiscoverRunning = true;
+ _DiscoverThread = new Thread(() => _Discover(Timeout));
+ _OnDiscovered = OnDiscovered;
+ _DiscoverThread.Start();
+ }
+
+ private void OnBroadcastEvent(object source, ElapsedEventArgs e)
+ {
+ Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ s.EnableBroadcast = true;
+ IPAddress broadcast = IPAddress.Parse(_BroadcastAddress);
+ byte[] sendbuf = Encoding.UTF8.GetBytes(_Keyword);
+ IPEndPoint ep = new IPEndPoint(broadcast, _Port);
+
+ s.SendTo(sendbuf, ep);
+ s.Close();
+ }
+
+ private void _Discover(int Timeout)
+ {
+ UdpClient listener = null;
+ Stopwatch timer = new Stopwatch();
+
+ List knownServer = new List();
+ bool foundSomething = false;
+ timer.Start();
+ while (_DiscoverRunning && timer.ElapsedMilliseconds < Timeout * 2)
+ {
+ try
+ {
+ listener = new UdpClient(_Port);
+ IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _Port);
+ listener.Client.ReceiveTimeout = Timeout;
+
+ byte[] bytes = listener.Receive(ref groupEP);
+ string message = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+
+ foundSomething = true;
+ if (!knownServer.Contains(groupEP.Address.ToString()))
+ {
+ knownServer.Add(groupEP.Address.ToString());
+ if (_OnDiscovered != null)
+ {
+ IPHostEntry e = Dns.GetHostEntry(groupEP.Address);
+ string hostname = e.HostName;
+
+ _OnDiscovered(groupEP.Address.ToString(), hostname);
+ }
+ }
+
+ listener.Close();
+ }
+ catch (Exception)
+ {
+ if (listener != null)
+ listener.Close();
+ }
+ }
+ _DiscoverRunning = false;
+
+ if (!foundSomething)
+ _OnDiscovered("Timeout", "unknown");
+ }
+ }
+}
diff --git a/ClientServerLib/ClientServerLib/ClientServerLib.csproj b/ClientServerLib/ClientServerLib/ClientServerLib.csproj
index d5bd8b7e..fbda0800 100644
--- a/ClientServerLib/ClientServerLib/ClientServerLib.csproj
+++ b/ClientServerLib/ClientServerLib/ClientServerLib.csproj
@@ -46,6 +46,7 @@
+
diff --git a/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs b/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs
index ff9f518b..ecfa087e 100644
--- a/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs
+++ b/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs
@@ -14,6 +14,8 @@ namespace Vocaluxe.Base.Server
private static UTF8Encoding encoder = new UTF8Encoding();
public static SHA256Managed SHA256 = new SHA256Managed();
+ public const string BroadcastKeyword = "I am a Vocaluxe Server";
+
#region Commands
public const int ResponseOK = 1;
public const int ResponseNOK = 2;
diff --git a/ClientServerLib/ClientTest/ClientTest.Designer.cs b/ClientServerLib/ClientTest/ClientTest.Designer.cs
index 65d2f867..33b815d3 100644
--- a/ClientServerLib/ClientTest/ClientTest.Designer.cs
+++ b/ClientServerLib/ClientTest/ClientTest.Designer.cs
@@ -49,6 +49,9 @@
this.btDown = new System.Windows.Forms.Button();
this.btSendAvatar = new System.Windows.Forms.Button();
this.btSendProfile = new System.Windows.Forms.Button();
+ this.btDiscover = new System.Windows.Forms.Button();
+ this.tbDiscoveredServer = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
@@ -251,11 +254,44 @@
this.btSendProfile.UseVisualStyleBackColor = true;
this.btSendProfile.Click += new System.EventHandler(this.btSendProfile_Click);
//
+ // btDiscover
+ //
+ this.btDiscover.Location = new System.Drawing.Point(831, 502);
+ this.btDiscover.Name = "btDiscover";
+ this.btDiscover.Size = new System.Drawing.Size(165, 23);
+ this.btDiscover.TabIndex = 16;
+ this.btDiscover.Text = "Discover";
+ this.btDiscover.UseVisualStyleBackColor = true;
+ this.btDiscover.Click += new System.EventHandler(this.btDiscover_Click);
+ //
+ // tbDiscoveredServer
+ //
+ this.tbDiscoveredServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.tbDiscoveredServer.Location = new System.Drawing.Point(15, 405);
+ this.tbDiscoveredServer.Multiline = true;
+ this.tbDiscoveredServer.Name = "tbDiscoveredServer";
+ this.tbDiscoveredServer.Size = new System.Drawing.Size(810, 120);
+ this.tbDiscoveredServer.TabIndex = 17;
+ this.tbDiscoveredServer.WordWrap = false;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 389);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(41, 13);
+ this.label1.TabIndex = 18;
+ this.label1.Text = "Server:";
+ //
// ClientTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1008, 550);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.tbDiscoveredServer);
+ this.Controls.Add(this.btDiscover);
this.Controls.Add(this.btSendProfile);
this.Controls.Add(this.btSendAvatar);
this.Controls.Add(this.btDown);
@@ -307,6 +343,9 @@
private System.Windows.Forms.Button btDown;
private System.Windows.Forms.Button btSendAvatar;
private System.Windows.Forms.Button btSendProfile;
+ private System.Windows.Forms.Button btDiscover;
+ private System.Windows.Forms.TextBox tbDiscoveredServer;
+ private System.Windows.Forms.Label label1;
}
}
diff --git a/ClientServerLib/ClientTest/ClientTest.cs b/ClientServerLib/ClientTest/ClientTest.cs
index f8c4a60d..af0be5b5 100644
--- a/ClientServerLib/ClientTest/ClientTest.cs
+++ b/ClientServerLib/ClientTest/ClientTest.cs
@@ -19,12 +19,15 @@ namespace ClientTest
public partial class ClientTest : Form
{
CClient client;
+ CDiscover discover;
+
private bool loggedIn;
public ClientTest()
{
client = new CClient();
loggedIn = false;
+ discover = new CDiscover(3000, CCommands.BroadcastKeyword);
InitializeComponent();
}
@@ -32,6 +35,7 @@ namespace ClientTest
protected override void OnClosing(CancelEventArgs e)
{
client.Close();
+ discover.Stop();
base.OnClosing(e);
}
@@ -262,5 +266,22 @@ namespace ClientTest
client.SendMessage(CCommands.CreateCommandSendProfile(data, "TestUser", 0), OnResponse);
}
}
+
+ private void btDiscover_Click(object sender, EventArgs e)
+ {
+ tbDiscoveredServer.Text = "Searching for Vocaluxe Server:\r\n";
+ discover.Discover(_OnDiscovered);
+ }
+
+ private void _OnDiscovered(string Address, string HostName)
+ {
+ this.Invoke((MethodInvoker)delegate
+ {
+ if (Address != "Timeout")
+ tbDiscoveredServer.Text += "IP = " + Address + "; HostName = " + HostName + "\r\n";
+ else
+ tbDiscoveredServer.Text += "Timeout" + "\r\n";
+ });
+ }
}
}
diff --git a/Output/ClientServerLib.dll b/Output/ClientServerLib.dll
index f59ca7e8..78c652b3 100644
Binary files a/Output/ClientServerLib.dll and b/Output/ClientServerLib.dll differ
diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs
index f82f81b5..78f7d189 100644
--- a/Vocaluxe/Base/Server/CVocaluxeServer.cs
+++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs
@@ -19,6 +19,7 @@ namespace Vocaluxe.Base.Server
static class CVocaluxeServer
{
private static CServer _Server;
+ private static CDiscover _Discover;
private static Dictionary _Clients;
public static CControllerFramework Controller = new CControllerFramework();
@@ -27,18 +28,23 @@ namespace Vocaluxe.Base.Server
{
_Clients = new Dictionary();
_Server = new CServer(RequestHandler, CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
+ _Discover = new CDiscover(CConfig.ServerPort, CCommands.ResponseKeyword);
Controller.Init();
}
public static void Start()
{
if (CConfig.ServerActive == EOffOn.TR_CONFIG_ON)
+ {
_Server.Start();
+ _Discover.StartBroadcasting();
+ }
}
public static void Close()
{
_Server.Stop();
+ _Discover.Stop();
_Clients = new Dictionary();
}