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

View File

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

View File

@ -77,18 +77,23 @@ namespace Steamworks
sw = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine( $"Socket: Listening" );
while ( Connected.Contains( singleClient ) )
{
Receive();
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" );
break;
}
}
Console.WriteLine( $"Socket: Closing connection because {Connected.Count()} Connected" );
await Task.Delay( 1000 );
Close();

View File

@ -58,6 +58,7 @@ namespace Steamworks
public static void Frame( HSteamPipe pipe )
{
SteamAPI_ManualDispatch_RunFrame( pipe );
SteamNetworkingUtils.OutputDebugMessages();
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
[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
internal void SetDebugOutputFunction( DebugOutputType eDetailLevel, NetDebugFunc pfnFunc )
internal void SetDebugOutputFunction( NetDebugOutput eDetailLevel, NetDebugFunc pfnFunc )
{
_SetDebugOutputFunction( Self, eDetailLevel, pfnFunc );
}

View File

@ -4,5 +4,5 @@ using System.Runtime.InteropServices;
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 );
}
/// <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; }
/// <summary>
@ -145,7 +159,66 @@ namespace Steamworks
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 )
{

View File

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