remove locking from other connections too
This commit is contained in:
		
							parent
							
								
									0e93b1356f
								
							
						
					
					
						commit
						d9e9c28976
					
				
					 4 changed files with 30 additions and 32 deletions
				
			
		|  | @ -27,8 +27,6 @@ internal sealed class ClientScreenServerConnection( | ||||||
|         ? null |         ? null | ||||||
|         : new PlayerScreenData(logger, player); |         : new PlayerScreenData(logger, player); | ||||||
| 
 | 
 | ||||||
|     protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer) => throw new UnreachableException(); |  | ||||||
| 
 |  | ||||||
|     protected override ValueTask HandleMessageAsync(Memory<byte> _) |     protected override ValueTask HandleMessageAsync(Memory<byte> _) | ||||||
|     { |     { | ||||||
|         if (_wantsFrameOnTick != 0) |         if (_wantsFrameOnTick != 0) | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ internal sealed class ControlsServerConnection( | ||||||
|         Shoot = 0x05 |         Shoot = 0x05 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer) |     protected override ValueTask HandleMessageAsync(Memory<byte> buffer) | ||||||
|     { |     { | ||||||
|         var type = (MessageType)buffer.Span[0]; |         var type = (MessageType)buffer.Span[0]; | ||||||
|         var control = (InputType)buffer.Span[1]; |         var control = (InputType)buffer.Span[1]; | ||||||
|  |  | ||||||
|  | @ -11,37 +11,37 @@ internal sealed class PlayerInfoConnection( | ||||||
|     MapEntityManager entityManager |     MapEntityManager entityManager | ||||||
| ) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0)) | ) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0)) | ||||||
| { | { | ||||||
|     private bool _wantsInfoOnTick = true; |     private int _wantsInfoOnTick = 1; | ||||||
|     private byte[] _lastMessage = []; |     private byte[]? _lastMessage = null; | ||||||
|  |     private byte[]? _nextMessage = null; | ||||||
| 
 | 
 | ||||||
|     protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer) |     protected override ValueTask HandleMessageAsync(Memory<byte> buffer) | ||||||
|     { |     { | ||||||
|         var response = GetMessageToSend(); |         var next = Interlocked.Exchange(ref _nextMessage, null); | ||||||
|         if (response == null) |         if (next != null) | ||||||
|         { |             return SendAndDisposeAsync(next); | ||||||
|             Logger.LogTrace("cannot respond directly, increasing wanted frames"); |  | ||||||
|             _wantsInfoOnTick = true; |  | ||||||
|             return ValueTask.CompletedTask; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         Logger.LogTrace("responding directly"); |         _wantsInfoOnTick = 1; | ||||||
|         return Socket.SendTextAsync(response); |         return ValueTask.CompletedTask; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public ValueTask OnGameTickAsync() => LockedAsync(() => |     public async ValueTask OnGameTickAsync() | ||||||
|     { |     { | ||||||
|         if (!_wantsInfoOnTick) |         await Task.Yield(); | ||||||
|             return ValueTask.CompletedTask; |  | ||||||
| 
 | 
 | ||||||
|         var response = GetMessageToSend(); |         var response = GetMessageToSend(); | ||||||
|         if (response == null) |         var wantsNow = Interlocked.Exchange(ref _wantsInfoOnTick, 0) != 0; | ||||||
|             return ValueTask.CompletedTask; |  | ||||||
| 
 | 
 | ||||||
|         Logger.LogTrace("responding indirectly"); |         if (wantsNow) | ||||||
|         return Socket.SendTextAsync(response); |         { | ||||||
|     }); |             await SendAndDisposeAsync(response); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|     private byte[]? GetMessageToSend() |         Interlocked.Exchange(ref _nextMessage, response); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private byte[] GetMessageToSend() | ||||||
|     { |     { | ||||||
|         var tank = entityManager.GetCurrentTankOfPlayer(player); |         var tank = entityManager.GetCurrentTankOfPlayer(player); | ||||||
| 
 | 
 | ||||||
|  | @ -53,11 +53,14 @@ internal sealed class PlayerInfoConnection( | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo); |         var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo); | ||||||
|         var response = JsonSerializer.SerializeToUtf8Bytes(info, AppSerializerContext.Default.PlayerInfo); |  | ||||||
| 
 | 
 | ||||||
|         if (response.SequenceEqual(_lastMessage)) |         // TODO: switch to async version with pre-allocated buffer / IMemoryOwner | ||||||
|             return null; |         return JsonSerializer.SerializeToUtf8Bytes(info, AppSerializerContext.Default.PlayerInfo); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         return _lastMessage = response; |     private async ValueTask SendAndDisposeAsync(byte[] data) | ||||||
|  |     { | ||||||
|  |         await Socket.SendTextAsync(data); | ||||||
|  |         Interlocked.Exchange(ref _lastMessage, data); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,10 +22,7 @@ internal abstract class WebsocketServerConnection( | ||||||
|         Logger.LogTrace("done receiving"); |         Logger.LogTrace("done receiving"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected virtual ValueTask HandleMessageAsync(Memory<byte> buffer) |     protected abstract ValueTask HandleMessageAsync(Memory<byte> buffer); | ||||||
|         => LockedAsync(() => HandleMessageLockedAsync(buffer)); |  | ||||||
| 
 |  | ||||||
|     protected abstract ValueTask HandleMessageLockedAsync(Memory<byte> buffer); |  | ||||||
| 
 | 
 | ||||||
|     protected async ValueTask LockedAsync(Func<ValueTask> action) |     protected async ValueTask LockedAsync(Func<ValueTask> action) | ||||||
|     { |     { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter