diff --git a/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin32.csproj b/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin32.csproj
index 03f2d4b..9b2faa0 100644
--- a/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin32.csproj
+++ b/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin32.csproj
@@ -99,6 +99,8 @@
+
+
diff --git a/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin64.csproj b/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin64.csproj
index 9f40a26..908c7b6 100644
--- a/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin64.csproj
+++ b/Facepunch.Steamworks.Test/Facepunch.Steamworks.TestWin64.csproj
@@ -99,6 +99,8 @@
+
+
diff --git a/Facepunch.Steamworks.Test/NetworkingSockets.cs b/Facepunch.Steamworks.Test/NetworkingSockets.cs
index bcaa549..16c1ea3 100644
--- a/Facepunch.Steamworks.Test/NetworkingSockets.cs
+++ b/Facepunch.Steamworks.Test/NetworkingSockets.cs
@@ -9,10 +9,10 @@
namespace Steamworks
{
- [TestClass]
+ [TestClass]
[DeploymentItem( "steam_api64.dll" )]
[DeploymentItem( "steam_api.dll" )]
- public class NetworkingSocketsTest
+ public partial class NetworkingSocketsTest
{
[TestMethod]
@@ -46,16 +46,18 @@ public async Task RelayEndtoEnd()
{
SteamNetworkingUtils.InitRelayNetworkAccess();
+ // For some reason giving steam a couple of seconds here
+ // seems to prevent it returning null connections from ConnectNormal
+ await Task.Delay( 2000 );
+
Console.WriteLine( $"----- Creating Socket Relay Socket.." );
- var socket = SteamNetworkingSockets.CreateRelaySocket( 7788 );
+ var socket = SteamNetworkingSockets.CreateRelaySocket( 6 );
var server = socket.RunAsync();
- Console.WriteLine( $"----- Created Relay Socket: {(uint)socket.Socket}" );
-
- await Task.Delay( 5000 );
+ await Task.Delay( 1000 );
Console.WriteLine( $"----- Connecting To Socket via SteamId ({SteamClient.SteamId})" );
- var connection = SteamNetworkingSockets.ConnectRelay( SteamClient.SteamId, 7788 );
+ var connection = SteamNetworkingSockets.ConnectRelay( SteamClient.SteamId, 6 );
var client = connection.RunAsync();
await Task.WhenAll( server, client );
@@ -64,231 +66,26 @@ public async Task RelayEndtoEnd()
[TestMethod]
public async Task NormalEndtoEnd()
{
+ // For some reason giving steam a couple of seconds here
+ // seems to prevent it returning null connections from ConnectNormal
+ await Task.Delay( 2000 );
+
+ //
+ // Start the server
+ //
+ Console.WriteLine( "CreateNormalSocket" );
var socket = SteamNetworkingSockets.CreateNormalSocket( NetAddress.AnyIp( 12445 ) );
var server = socket.RunAsync();
- await Task.Delay( 5000 );
-
+ //
+ // Start the client
+ //
+ Console.WriteLine( "ConnectNormal" );
var connection = SteamNetworkingSockets.ConnectNormal( NetAddress.From( System.Net.IPAddress.Parse( "127.0.0.1" ), 12445 ) );
var client = connection.RunAsync();
await Task.WhenAll( server, client );
}
-
- private class TestConnectionInterface : ConnectionInterface
- {
- public override void OnConnectionChanged( ConnectionInfo data )
- {
- Console.WriteLine( $"[Connection][{Connection}] [{data.State}]" );
-
- base.OnConnectionChanged( data );
- }
-
- public override void OnConnecting( ConnectionInfo data )
- {
- Console.WriteLine( $" - OnConnecting" );
- base.OnConnecting( data );
- }
-
- ///
- /// Client is connected. They move from connecting to Connections
- ///
- public override void OnConnected( ConnectionInfo data )
- {
- Console.WriteLine( $" - OnConnected" );
- base.OnConnected( data );
- }
-
- ///
- /// The connection has been closed remotely or disconnected locally. Check data.State for details.
- ///
- public override void OnDisconnected( ConnectionInfo data )
- {
- Console.WriteLine( $" - OnDisconnected" );
- base.OnDisconnected( data );
- }
-
- internal async Task RunAsync()
- {
- Console.WriteLine( "[Connection] RunAsync" );
-
- var sw = System.Diagnostics.Stopwatch.StartNew();
-
- while ( Connecting )
- {
- await Task.Delay( 10 );
-
- if ( sw.Elapsed.TotalSeconds > 30 )
- break;
- }
-
- if ( !Connected )
- {
- Console.WriteLine( "[Connection] Couldn't connect!" );
- Console.WriteLine( Connection.DetailedStatus() );
- return;
- }
-
- Console.WriteLine( "[Connection] Hey We're Connected!" );
-
-
- sw = System.Diagnostics.Stopwatch.StartNew();
- while ( Connected )
- {
- Receive();
- await Task.Delay( 100 );
-
- if ( sw.Elapsed.TotalSeconds > 10 )
- {
- Assert.Fail( "Client Took Too Long" );
- break;
- }
- }
- }
-
- public override unsafe void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel )
- {
- // We're only sending strings, so it's fine to read this like this
- var str = UTF8Encoding.UTF8.GetString( (byte*) data, size );
-
- Console.WriteLine( $"[Connection][{messageNum}][{recvTime}][{channel}] \"{str}\"" );
-
- if ( str.Contains( "Hello" ) )
- {
- Connection.SendMessage( "Hello, How are you!?" );
-
- Connection.SendMessage( "How do you like 20 messages in a row?" );
-
- for ( int i=0; i<20; i++ )
- {
- Connection.SendMessage( $"BLAMMO!" );
- }
- }
-
- if ( str.Contains( "status" ))
- {
- Console.WriteLine( Connection.DetailedStatus() );
- }
-
- if ( str.Contains( "how about yourself" ) )
- {
- Connection.SendMessage( "I'm great, but I have to go now, bye." );
- }
-
- if ( str.Contains( "hater" ) )
- {
- Close();
- }
-
- }
- }
-
-
- private class TestSocketInterface : SocketInterface
- {
- public bool HasFinished = false;
-
- public override void OnConnectionChanged( Connection connection, ConnectionInfo data )
- {
- Console.WriteLine( $"[Socket{Socket}][{connection}] [{data.State}]" );
-
- base.OnConnectionChanged( connection, data );
- }
-
- public override void OnConnecting( Connection connection, ConnectionInfo data )
- {
- Console.WriteLine( $" - OnConnecting" );
- base.OnConnecting( connection, data );
- }
-
- ///
- /// Client is connected. They move from connecting to Connections
- ///
- public override void OnConnected( Connection connection, ConnectionInfo data )
- {
- Console.WriteLine( $" - OnConnected" );
- base.OnConnected( connection, data );
- }
-
- ///
- /// The connection has been closed remotely or disconnected locally. Check data.State for details.
- ///
- public override void OnDisconnected( Connection connection, ConnectionInfo data )
- {
- Console.WriteLine( $" - OnDisconnected" );
- base.OnDisconnected( connection, data );
- }
-
- internal async Task RunAsync()
- {
- var sw = System.Diagnostics.Stopwatch.StartNew();
-
- while ( Connected.Count == 0 )
- {
- await Task.Delay( 10 );
-
- if ( sw.Elapsed.TotalSeconds > 2 )
- {
- Assert.Fail( "Client Took Too Long To Connect" );
- break;
- }
- }
-
- await Task.Delay( 1000 );
-
- var singleClient = Connected.First();
-
- singleClient.SendMessage( "Hey?" );
- await Task.Delay( 100 );
- singleClient.SendMessage( "Anyone?" );
- await Task.Delay( 100 );
- singleClient.SendMessage( "What's this?" );
- await Task.Delay( 100 );
- singleClient.SendMessage( "What's your status?" );
- await Task.Delay( 10 );
- singleClient.SendMessage( "Greetings!!??" );
- await Task.Delay( 100 );
- singleClient.SendMessage( "Hello Client!?" );
-
- sw = System.Diagnostics.Stopwatch.StartNew();
-
- while ( Connected.Contains( singleClient ) )
- {
- Receive();
- await Task.Delay( 100 );
-
- if ( sw.Elapsed.TotalSeconds > 10 )
- {
- Assert.Fail( "Socket Took Too Long" );
- break;
- }
- }
-
- await Task.Delay( 1000 );
-
- Close();
- }
-
- public override unsafe void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
- {
- // We're only sending strings, so it's fine to read this like this
- var str = UTF8Encoding.UTF8.GetString( (byte*)data, size );
-
- Console.WriteLine( $"[SOCKET][{connection}[{identity}][{messageNum}][{recvTime}][{channel}] \"{str}\"" );
-
- if ( str.Contains( "Hello, How are you" ) )
- {
- connection.SendMessage( "I'm great thanks, how about yourself?" );
- }
-
- if ( str.Contains( "bye" ) )
- {
- connection.SendMessage( "See you later, hater." );
- connection.Flush();
- connection.Close( true, 10, "Said Bye" );
- }
- }
- }
}
}
\ No newline at end of file
diff --git a/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestConnectionInterface.cs b/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestConnectionInterface.cs
new file mode 100644
index 0000000..e5b5756
--- /dev/null
+++ b/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestConnectionInterface.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Steamworks.Data;
+
+namespace Steamworks
+{
+ public partial class NetworkingSocketsTest
+ {
+ private class TestConnectionInterface : ConnectionInterface
+ {
+ public override void OnConnectionChanged( ConnectionInfo data )
+ {
+ Console.WriteLine( $"[Connection][{Connection}] [{data.State}]" );
+
+ base.OnConnectionChanged( data );
+ }
+
+ public override void OnConnecting( ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnConnecting" );
+ base.OnConnecting( data );
+ }
+
+ ///
+ /// Client is connected. They move from connecting to Connections
+ ///
+ public override void OnConnected( ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnConnected" );
+ base.OnConnected( data );
+ }
+
+ ///
+ /// The connection has been closed remotely or disconnected locally. Check data.State for details.
+ ///
+ public override void OnDisconnected( ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnDisconnected" );
+ base.OnDisconnected( data );
+ }
+
+ internal async Task RunAsync()
+ {
+ Console.WriteLine( "[Connection] RunAsync" );
+
+ var sw = System.Diagnostics.Stopwatch.StartNew();
+
+ while ( Connecting )
+ {
+ await Task.Delay( 10 );
+
+ if ( sw.Elapsed.TotalSeconds > 30 )
+ break;
+ }
+
+ if ( !Connected )
+ {
+ Console.WriteLine( "[Connection] Couldn't connect!" );
+ Console.WriteLine( Connection.DetailedStatus() );
+ return;
+ }
+
+ Console.WriteLine( "[Connection] Hey We're Connected!" );
+
+
+ sw = System.Diagnostics.Stopwatch.StartNew();
+ while ( Connected )
+ {
+ Receive();
+ await Task.Delay( 100 );
+
+ if ( sw.Elapsed.TotalSeconds > 10 )
+ {
+ Assert.Fail( "Client Took Too Long" );
+ break;
+ }
+ }
+ }
+
+ public override unsafe void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel )
+ {
+ // We're only sending strings, so it's fine to read this like this
+ var str = UTF8Encoding.UTF8.GetString( (byte*) data, size );
+
+ Console.WriteLine( $"[Connection][{messageNum}][{recvTime}][{channel}] \"{str}\"" );
+
+ if ( str.Contains( "Hello" ) )
+ {
+ Connection.SendMessage( "Hello, How are you!?" );
+
+ Connection.SendMessage( "How do you like 20 messages in a row?" );
+
+ for ( int i=0; i<20; i++ )
+ {
+ Connection.SendMessage( $"BLAMMO!" );
+ }
+ }
+
+ if ( str.Contains( "status" ))
+ {
+ Console.WriteLine( Connection.DetailedStatus() );
+ }
+
+ if ( str.Contains( "how about yourself" ) )
+ {
+ Connection.SendMessage( "I'm great, but I have to go now, bye." );
+ }
+
+ if ( str.Contains( "hater" ) )
+ {
+ Close();
+ }
+
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestSocketInterface.cs b/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestSocketInterface.cs
new file mode 100644
index 0000000..8941fcb
--- /dev/null
+++ b/Facepunch.Steamworks.Test/NetworkingSocketsTest.TestSocketInterface.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Steamworks.Data;
+
+namespace Steamworks
+{
+ public partial class NetworkingSocketsTest
+ {
+ private class TestSocketInterface : SocketInterface
+ {
+ public bool HasFinished = false;
+
+ public override void OnConnectionChanged( Connection connection, ConnectionInfo data )
+ {
+ Console.WriteLine( $"[Socket{Socket}][{connection}] [{data.State}]" );
+
+ base.OnConnectionChanged( connection, data );
+ }
+
+ public override void OnConnecting( Connection connection, ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnConnecting" );
+ base.OnConnecting( connection, data );
+ }
+
+ ///
+ /// Client is connected. They move from connecting to Connections
+ ///
+ public override void OnConnected( Connection connection, ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnConnected" );
+ base.OnConnected( connection, data );
+ }
+
+ ///
+ /// The connection has been closed remotely or disconnected locally. Check data.State for details.
+ ///
+ public override void OnDisconnected( Connection connection, ConnectionInfo data )
+ {
+ Console.WriteLine( $" - OnDisconnected" );
+ base.OnDisconnected( connection, data );
+ }
+
+ internal async Task RunAsync()
+ {
+ var sw = System.Diagnostics.Stopwatch.StartNew();
+
+ while ( Connected.Count == 0 )
+ {
+ await Task.Delay( 10 );
+
+ if ( sw.Elapsed.TotalSeconds > 5 )
+ {
+ Assert.Fail( "Client Took Too Long To Connect" );
+ break;
+ }
+ }
+
+ await Task.Delay( 1000 );
+
+ var singleClient = Connected.First();
+
+ singleClient.SendMessage( "Hey?" );
+ await Task.Delay( 100 );
+ singleClient.SendMessage( "Anyone?" );
+ await Task.Delay( 100 );
+ singleClient.SendMessage( "What's this?" );
+ await Task.Delay( 100 );
+ singleClient.SendMessage( "What's your status?" );
+ await Task.Delay( 10 );
+ singleClient.SendMessage( "Greetings!!??" );
+ await Task.Delay( 100 );
+ singleClient.SendMessage( "Hello Client!?" );
+
+ sw = System.Diagnostics.Stopwatch.StartNew();
+
+ while ( Connected.Contains( singleClient ) )
+ {
+ Receive();
+ await Task.Delay( 100 );
+
+ if ( sw.Elapsed.TotalSeconds > 10 )
+ {
+ Assert.Fail( "Socket Took Too Long" );
+ break;
+ }
+ }
+
+ await Task.Delay( 1000 );
+
+ Close();
+ }
+
+ public override unsafe void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
+ {
+ // We're only sending strings, so it's fine to read this like this
+ var str = UTF8Encoding.UTF8.GetString( (byte*)data, size );
+
+ Console.WriteLine( $"[SOCKET][{connection}[{identity}][{messageNum}][{recvTime}][{channel}] \"{str}\"" );
+
+ if ( str.Contains( "Hello, How are you" ) )
+ {
+ connection.SendMessage( "I'm great thanks, how about yourself?" );
+ }
+
+ if ( str.Contains( "bye" ) )
+ {
+ connection.SendMessage( "See you later, hater." );
+ connection.Flush();
+ connection.Close( true, 10, "Said Bye" );
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Facepunch.Steamworks/Classes/SocketInterface.cs b/Facepunch.Steamworks/Classes/SocketInterface.cs
index d6998d1..44c13c7 100644
--- a/Facepunch.Steamworks/Classes/SocketInterface.cs
+++ b/Facepunch.Steamworks/Classes/SocketInterface.cs
@@ -11,10 +11,28 @@ public class SocketInterface
public List Connected = new List();
public Socket Socket { get; internal set; }
- public bool Close() => Socket.Close();
-
public override string ToString() => Socket.ToString();
+ internal HSteamNetPollGroup pollGroup;
+
+ internal void Initialize()
+ {
+ pollGroup = SteamNetworkingSockets.Internal.CreatePollGroup();
+ }
+
+ public bool Close()
+ {
+ if ( SteamNetworkingSockets.Internal.IsValid )
+ {
+ SteamNetworkingSockets.Internal.DestroyPollGroup( pollGroup );
+ Socket.Close();
+ }
+
+ pollGroup = 0;
+ Socket = 0;
+ return true;
+ }
+
public virtual void OnConnectionChanged( Connection connection, ConnectionInfo data )
{
switch ( data.State )
@@ -40,6 +58,8 @@ public virtual void OnConnecting( Connection connection, ConnectionInfo data )
{
connection.Accept();
Connecting.Add( connection );
+
+ SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup );
}
///
@@ -67,10 +87,10 @@ public void Receive( int bufferSize = 32 )
int processed = 0;
IntPtr messageBuffer = Marshal.AllocHGlobal( IntPtr.Size * bufferSize );
- /*
+
try
{
- processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnListenSocket( Socket, messageBuffer, bufferSize );
+ processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnPollGroup( pollGroup, messageBuffer, bufferSize );
for ( int i = 0; i < processed; i++ )
{
@@ -81,7 +101,7 @@ public void Receive( int bufferSize = 32 )
{
Marshal.FreeHGlobal( messageBuffer );
}
- */
+
//
// Overwhelmed our buffer, keep going
diff --git a/Facepunch.Steamworks/SteamNetworkingSockets.cs b/Facepunch.Steamworks/SteamNetworkingSockets.cs
index 09e3bff..6e2b38f 100644
--- a/Facepunch.Steamworks/SteamNetworkingSockets.cs
+++ b/Facepunch.Steamworks/SteamNetworkingSockets.cs
@@ -73,9 +73,10 @@ internal static void SetConnectionInterface( uint id, ConnectionInterface iface
internal static void InstallEvents( bool server = false )
{
- Dispatch.Install( x => ConnectionStatusChanged( x ), server );
+ Dispatch.Install( ConnectionStatusChanged, server );
}
+
private static void ConnectionStatusChanged( SteamNetConnectionStatusChangedCallback_t data )
{
//
@@ -107,6 +108,8 @@ private static void ConnectionStatusChanged( SteamNetConnectionStatusChangedCall
var t = new T();
var options = new NetKeyValue[0];
t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
+ t.Initialize();
+
SetSocketInterface( t.Socket.Id, t );
return t;
}
diff --git a/Facepunch.Steamworks/Structs/Connection.cs b/Facepunch.Steamworks/Structs/Connection.cs
index 48c2046..eaac660 100644
--- a/Facepunch.Steamworks/Structs/Connection.cs
+++ b/Facepunch.Steamworks/Structs/Connection.cs
@@ -94,27 +94,5 @@ public string DetailedStatus()
return strVal;
}
-
- /*
- [ThreadStatic]
- private static SteamNetworkingMessage_t[] messageBuffer;
-
- public IEnumerable Messages
- {
- get
- {
- if ( messageBuffer == null )
- messageBuffer = new SteamNetworkingMessage_t[128];
-
- var num = SteamNetworkingSockets.Internal.ReceiveMessagesOnConnection( this, ref messageBuffer, messageBuffer.Length );
-
- for ( int i = 0; i < num; i++)
- {
- yield return messageBuffer[i];
- messageBuffer[i].Release();
- }
- }
- }*/
-
}
}
diff --git a/Facepunch.Steamworks/Structs/NetIdentity.cs b/Facepunch.Steamworks/Structs/NetIdentity.cs
index c466c99..aaa2c85 100644
--- a/Facepunch.Steamworks/Structs/NetIdentity.cs
+++ b/Facepunch.Steamworks/Structs/NetIdentity.cs
@@ -24,7 +24,12 @@ public static implicit operator SteamId( NetIdentity value )
return value.steamID;
}
- public override string ToString() => $"{type};{m_cbSize};{steamID}";
+ public override string ToString()
+ {
+ var id = this;
+ SteamNetworkingUtils.Internal.SteamNetworkingIdentity_ToString( ref id, out var str );
+ return str;
+ }
internal enum IdentityType
{
diff --git a/Facepunch.Steamworks/Structs/Socket.cs b/Facepunch.Steamworks/Structs/Socket.cs
index 864223e..24cbc71 100644
--- a/Facepunch.Steamworks/Structs/Socket.cs
+++ b/Facepunch.Steamworks/Structs/Socket.cs
@@ -17,7 +17,7 @@ public struct Socket
///
public bool Close()
{
- return SteamNetworkingSockets.Internal.CloseListenSocket( this );
+ return SteamNetworkingSockets.Internal.CloseListenSocket( Id );
}
public SocketInterface Interface