Added SteamNetworkUtils.OnDebugOutput, DebugLevel

This commit is contained in:
Garry Newman 2020-02-24 11:33:29 +00:00
parent 41c1d0da08
commit 44196682c8
9 changed files with 106 additions and 23 deletions

View File

@ -14,10 +14,17 @@ namespace Steamworks
[DeploymentItem( "steam_api.dll" )] [DeploymentItem( "steam_api.dll" )]
public partial class NetworkingSocketsTest public partial class NetworkingSocketsTest
{ {
void DebugOutput( NetDebugOutput type, string text )
{
Console.WriteLine( $"[NET:{type}]\t\t{text}" );
}
[TestMethod] [TestMethod]
public async Task CreateRelayServer() public async Task CreateRelayServer()
{ {
SteamNetworkingUtils.DebugLevel = NetDebugOutput.Everything;
SteamNetworkingUtils.OnDebugOutput += DebugOutput;
var si = SteamNetworkingSockets.CreateRelaySocket<TestSocketInterface>(); var si = SteamNetworkingSockets.CreateRelaySocket<TestSocketInterface>();
Console.WriteLine( $"Created Socket: {si}" ); Console.WriteLine( $"Created Socket: {si}" );
@ -31,6 +38,9 @@ namespace Steamworks
[TestMethod] [TestMethod]
public async Task CreateNormalServer() public async Task CreateNormalServer()
{ {
SteamNetworkingUtils.DebugLevel = NetDebugOutput.Everything;
SteamNetworkingUtils.OnDebugOutput += DebugOutput;
var si = SteamNetworkingSockets.CreateNormalSocket<TestSocketInterface>( Data.NetAddress.AnyIp( 21893 ) ); var si = SteamNetworkingSockets.CreateNormalSocket<TestSocketInterface>( Data.NetAddress.AnyIp( 21893 ) );
Console.WriteLine( $"Created Socket: {si}" ); Console.WriteLine( $"Created Socket: {si}" );
@ -45,6 +55,8 @@ namespace Steamworks
public async Task RelayEndtoEnd() public async Task RelayEndtoEnd()
{ {
SteamNetworkingUtils.InitRelayNetworkAccess(); SteamNetworkingUtils.InitRelayNetworkAccess();
SteamNetworkingUtils.DebugLevel = NetDebugOutput.Warning;
SteamNetworkingUtils.OnDebugOutput += DebugOutput;
// For some reason giving steam a couple of seconds here // For some reason giving steam a couple of seconds here
// seems to prevent it returning null connections from ConnectNormal // seems to prevent it returning null connections from ConnectNormal
@ -66,6 +78,9 @@ namespace Steamworks
[TestMethod] [TestMethod]
public async Task NormalEndtoEnd() public async Task NormalEndtoEnd()
{ {
SteamNetworkingUtils.DebugLevel = NetDebugOutput.Everything;
SteamNetworkingUtils.OnDebugOutput += DebugOutput;
// For some reason giving steam a couple of seconds here // For some reason giving steam a couple of seconds here
// seems to prevent it returning null connections from ConnectNormal // seems to prevent it returning null connections from ConnectNormal
await Task.Delay( 2000 ); await Task.Delay( 2000 );

View File

@ -47,6 +47,7 @@ namespace Steamworks
var sw = System.Diagnostics.Stopwatch.StartNew(); var sw = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine( "[Connection] Connecting" );
while ( Connecting ) while ( Connecting )
{ {
await Task.Delay( 10 ); await Task.Delay( 10 );
@ -88,14 +89,18 @@ namespace Steamworks
if ( str.Contains( "Hello" ) ) if ( str.Contains( "Hello" ) )
{ {
Console.WriteLine( $"[Connection][{messageNum}][{recvTime}][{channel}] Sending: Hello, How are you!?" );
Connection.SendMessage( "Hello, How are you!?" ); Connection.SendMessage( "Hello, How are you!?" );
Console.WriteLine( $"[Connection][{messageNum}][{recvTime}][{channel}] Sending: How do you like 20 messages in a row?" );
Connection.SendMessage( "How do you like 20 messages in a row?" ); Connection.SendMessage( "How do you like 20 messages in a row?" );
for ( int i=0; i<20; i++ ) for ( int i=0; i<20; i++ )
{ {
Connection.SendMessage( $"BLAMMO!" ); Connection.SendMessage( $"BLAMMO!" );
} }
Connection.Flush();
} }
if ( str.Contains( "status" )) if ( str.Contains( "status" ))

View File

@ -77,18 +77,23 @@ namespace Steamworks
sw = System.Diagnostics.Stopwatch.StartNew(); sw = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine( $"Socket: Listening" );
while ( Connected.Contains( singleClient ) ) while ( Connected.Contains( singleClient ) )
{ {
Receive(); Receive();
await Task.Delay( 100 ); await Task.Delay( 100 );
if ( sw.Elapsed.TotalSeconds > 10 ) if ( sw.Elapsed.TotalSeconds > 5 )
{ {
Console.WriteLine( "Socket: This all took too long - throwing an exception" );
Assert.Fail( "Socket Took Too Long" ); Assert.Fail( "Socket Took Too Long" );
break; break;
} }
} }
Console.WriteLine( $"Socket: Closing connection because {Connected.Count()} Connected" );
await Task.Delay( 1000 ); await Task.Delay( 1000 );
Close(); Close();

View File

@ -58,6 +58,7 @@ namespace Steamworks
public static void Frame( HSteamPipe pipe ) public static void Frame( HSteamPipe pipe )
{ {
SteamAPI_ManualDispatch_RunFrame( pipe ); SteamAPI_ManualDispatch_RunFrame( pipe );
SteamNetworkingUtils.OutputDebugMessages();
CallbackMsg_t msg = default; CallbackMsg_t msg = default;

View File

@ -1,17 +0,0 @@
namespace Steamworks.Data
{
enum DebugOutputType : int
{
None = 0,
Bug = 1, // You used the API incorrectly, or an internal error happened
Error = 2, // Run-time error condition that isn't the result of a bug. (E.g. we are offline, cannot bind a port, etc)
Important = 3, // Nothing is wrong, but this is an important notification
Warning = 4,
Msg = 5, // Recommended amount
Verbose = 6, // Quite a bit
Debug = 7, // Practically everything
Everything = 8, // Wall of text, detailed packet contents breakdown, etc
Force32Bit = 0x7fffffff
};
}

View File

@ -178,10 +178,10 @@ namespace Steamworks
#region FunctionMeta #region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamNetworkingUtils_SetDebugOutputFunction", CallingConvention = Platform.CC)] [DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamNetworkingUtils_SetDebugOutputFunction", CallingConvention = Platform.CC)]
private static extern void _SetDebugOutputFunction( IntPtr self, DebugOutputType eDetailLevel, NetDebugFunc pfnFunc ); private static extern void _SetDebugOutputFunction( IntPtr self, NetDebugOutput eDetailLevel, NetDebugFunc pfnFunc );
#endregion #endregion
internal void SetDebugOutputFunction( DebugOutputType eDetailLevel, NetDebugFunc pfnFunc ) internal void SetDebugOutputFunction( NetDebugOutput eDetailLevel, NetDebugFunc pfnFunc )
{ {
_SetDebugOutputFunction( Self, eDetailLevel, pfnFunc ); _SetDebugOutputFunction( Self, eDetailLevel, pfnFunc );
} }

View File

@ -4,5 +4,5 @@ using System.Runtime.InteropServices;
namespace Steamworks.Data namespace Steamworks.Data
{ {
delegate void NetDebugFunc( DebugOutputType nType, string pszMsg ); delegate void NetDebugFunc( NetDebugOutput nType, string pszMsg );
} }

View File

@ -28,6 +28,20 @@ namespace Steamworks
}, server ); }, server );
} }
/// <summary>
/// A function to receive debug network information on. This will do nothing
/// unless you set DebugLevel to something other than None.
///
/// You should set this to an appropriate level instead of setting it to the highest
/// and then filtering it by hand because a lot of energy is used by creating the strings
/// and your frame rate will tank and you won't know why.
/// </summary>
public static event Action<NetDebugOutput, string> OnDebugOutput;
/// <summary>
/// The latest available status gathered from the SteamRelayNetworkStatus callback
/// </summary>
public static SteamNetworkingAvailability Status { get; private set; } public static SteamNetworkingAvailability Status { get; private set; }
/// <summary> /// <summary>
@ -145,7 +159,66 @@ namespace Steamworks
set => SetConfigFloat( NetConfig.FakePacketLag_Recv, value ); set => SetConfigFloat( NetConfig.FakePacketLag_Recv, value );
} }
#region Config Internals
/// <summary>
/// Get Debug Information via OnDebugOutput event
///
/// Except when debugging, you should only use NetDebugOutput.Msg
/// or NetDebugOutput.Warning. For best performance, do NOT
/// request a high detail level and then filter out messages in the callback.
///
/// This incurs all of the expense of formatting the messages, which are then discarded.
/// Setting a high priority value (low numeric value) here allows the library to avoid
/// doing this work.
/// </summary>
public static NetDebugOutput DebugLevel
{
get => _debugLevel;
set
{
_debugLevel = value;
Internal.SetDebugOutputFunction( value, OnDebugMessage );
}
}
/// <summary>
/// So we can remember and provide a Get for DebugLEvel
/// </summary>
private static NetDebugOutput _debugLevel;
struct DebugMessage
{
public NetDebugOutput Type;
public string Msg;
}
private static System.Collections.Concurrent.ConcurrentQueue<DebugMessage> debugMessages = new System.Collections.Concurrent.ConcurrentQueue<DebugMessage>();
/// <summary>
/// This can be called from other threads - so we're going to queue these up and process them in a safe place.
/// </summary>
private static void OnDebugMessage( NetDebugOutput nType, string pszMsg )
{
debugMessages.Enqueue( new DebugMessage { Type = nType, Msg = pszMsg } );
}
/// <summary>
/// Called regularly from the Dispatch loop so we can provide a timely
/// stream of messages.
/// </summary>
internal static void OutputDebugMessages()
{
if ( debugMessages.IsEmpty )
return;
while ( debugMessages.TryDequeue( out var result ) )
{
OnDebugOutput?.Invoke( result.Type, result.Msg );
}
}
#region Config Internals
internal unsafe static bool GetConfigInt( NetConfig type, int value ) internal unsafe static bool GetConfigInt( NetConfig type, int value )
{ {

View File

@ -47,7 +47,7 @@ public static class Cleanup
type = type.Replace( "SteamNetConnectionInfo_t", "ConnectionInfo" ); type = type.Replace( "SteamNetConnectionInfo_t", "ConnectionInfo" );
type = type.Replace( "SteamNetworkingConnectionState", "ConnectionState" ); type = type.Replace( "SteamNetworkingConnectionState", "ConnectionState" );
type = type.Replace( "SteamNetworkingMicroseconds", "long" ); type = type.Replace( "SteamNetworkingMicroseconds", "long" );
type = type.Replace( "SteamNetworkingSocketsDebugOutputType", "DebugOutputType" ); type = type.Replace( "SteamNetworkingSocketsDebugOutputType", "NetDebugOutput" );
type = type.Replace( "SteamNetworkingGetConfigValueResult", "NetConfigResult" ); type = type.Replace( "SteamNetworkingGetConfigValueResult", "NetConfigResult" );
type = type.Replace( "SteamInputType", "InputType" ); type = type.Replace( "SteamInputType", "InputType" );
type = type.Replace( "InputDigitalActionData_t", "DigitalState" ); type = type.Replace( "InputDigitalActionData_t", "DigitalState" );
@ -136,6 +136,7 @@ public static class Cleanup
if ( name == "NetConnectionEnd" ) return "public"; if ( name == "NetConnectionEnd" ) return "public";
if ( name == "NetIdentity" ) return "public"; if ( name == "NetIdentity" ) return "public";
if ( name == "NetAddress" ) return "public"; if ( name == "NetAddress" ) return "public";
if ( name == "NetDebugOutput" ) return "public";
return "internal"; return "internal";
} }