Skip to content

Commit

Permalink
Commit some added safety and logging
Browse files Browse the repository at this point in the history
  • Loading branch information
aschneem committed Jul 23, 2024
1 parent 52c12b0 commit c61c3be
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 10 deletions.
34 changes: 34 additions & 0 deletions frosthaven_assistant_server/lib/connection_health.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class ConnectionHealth{
DateTime creation = DateTime.now();
int pingsSent = 0;
int pongsReceived = 0;
DateTime? lastMessageSent;
DateTime? lastMessageReceived;
int messageSent = 0;
int messageRecieved = 0;

logPing(){
pingsSent ++;
lastMessageSent = DateTime.now();
}

logPong(){
pongsReceived ++;
lastMessageReceived = DateTime.now();
}

logMessageSent(){
messageSent ++;
lastMessageSent = DateTime.now();
}

logMessageReceived(){
messageRecieved ++;
lastMessageReceived = DateTime.now();
}

@override
String toString() {
return "Created: $creation Sent: $lastMessageSent Recieved: $lastMessageReceived pings $pongsReceived/$pingsSent messages $messageSent | $messageRecieved";
}
}
14 changes: 9 additions & 5 deletions frosthaven_assistant_server/lib/game_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class StateUpdateMessage {

abstract class GameServer {

final int serverVersion = 190;
final int serverVersion = 191;

ServerSocket? _serverSocket;
ServerSocket? get serverSocket {
Expand Down Expand Up @@ -122,14 +122,18 @@ abstract class GameServer {
resetState();
}

void handleConnection(Socket client) {
client.setOption(SocketOption.tcpNoDelay, true);
client.encoding = utf8;

void logHandleConnection(Socket client){
String info = 'Connection from'
' ${client.remoteAddress.address}:${client.remotePort}';
log(info);
setNetworkMessage(info);
}

void handleConnection(Socket client) {
client.setOption(SocketOption.tcpNoDelay, true);
client.encoding = utf8;

logHandleConnection(client);

addClientConnection(client);

Expand Down
7 changes: 6 additions & 1 deletion frosthaven_assistant_server/lib/server_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ class ServerState {
print('server sends, undo index: $commandIndex, description:${commandDescriptions[commandIndex]}');
//should send a special undo message? yes
commandIndex--;
return "Index:${commandIndex}Description:${commandDescriptions[commandIndex]}GameState:${gameSaveStates[commandIndex]!.getState()}";
if (commandIndex >= 0){
return "Index:${commandIndex}Description:${commandDescriptions[commandIndex]}GameState:${gameSaveStates[commandIndex]!.getState()}";
} else {
commandIndex = 0;
return "";
}
}
return "";
}
Expand Down
75 changes: 71 additions & 4 deletions frosthaven_assistant_server/lib/standalone_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
import 'dart:developer';
import 'dart:io';

import 'package:frosthaven_assistant_server/connection_health.dart';
import 'package:frosthaven_assistant_server/game_server.dart';
import 'package:frosthaven_assistant_server/server_state.dart';

class StandaloneServer extends GameServer {

final List<Socket> _clientConnections = List.empty(growable: true);
final ServerState _state = ServerState();
final Map<Socket,ConnectionHealth> _connectionHealth = {};
int pingCount = 0;


@override
void addClientConnection(Socket client) {
print("Add client connection ${safeGetClientAddress(client)}");
_connectionHealth[client] = ConnectionHealth();
_clientConnections.add(client);
}

Expand Down Expand Up @@ -45,15 +50,27 @@ class StandaloneServer extends GameServer {

@override
void removeAllClientConnections() {
print("Remove all Client Connections");
for (var client in _clientConnections) {
client.close();
print("Close Connection ${safeGetClientAddress(client)} ${_connectionHealth[client]}");
try {
client.close();
} catch (exception) {
print("Client already closed");
}
}
_clientConnections.clear();
}

@override
void removeClientConnection(Socket client) {
client.close();
print("Remove client connection ${safeGetClientAddress(client)}");
print("Close Connection ${safeGetClientAddress(client)} ${_connectionHealth[client]}");
try {
client.close();
} catch (exception) {
print("Client already closed");
}
_clientConnections.remove(client);
}

Expand Down Expand Up @@ -102,14 +119,19 @@ class StandaloneServer extends GameServer {
void sendToOthers(String data, Socket client) {
final String message = _createMessage(data);
for(Socket clientConnection in _clientConnections){
if (client.remoteAddress != clientConnection.remoteAddress || clientConnection.remotePort != client.remotePort){
_writeToClient(clientConnection, message);
try {
if (client.remoteAddress != clientConnection.remoteAddress || clientConnection.remotePort != client.remotePort){
_writeToClient(clientConnection, message);
}
} catch (exception) {
print("Attempted to access properties on a closed client $exception");
}
}
}

void _writeToClient(Socket client, String message) {
try {
_connectionHealth[client]?.logMessageSent();
client.write(message);
} catch (error) {
print(error);
Expand All @@ -126,6 +148,8 @@ class StandaloneServer extends GameServer {
String message = _state.undoState();
if (message.isNotEmpty) {
send(message);
} else {
setNetworkMessage("Unable to undo command");
}
}

Expand Down Expand Up @@ -166,15 +190,58 @@ class StandaloneServer extends GameServer {
if (serverSocket != null && serverEnabled) {
Future.delayed(const Duration(seconds: 5), () {
send("ping");
for(Socket client in _clientConnections){
_connectionHealth[client]?.logPing();
}
pingCount ++;
if (pingCount % 30 == 0){
printHealthReport();
}
sendPing();
});
}
}

@override
void handlePongMessage(Socket client){
super.handlePongMessage(client);
_connectionHealth[client]?.logPong();
}

@override
void processMessages(String socketMessages, Socket client){
_connectionHealth[client]?.logMessageReceived();
super.processMessages(socketMessages, client);
}

String _createMessage(String data){
const beginning = "S3nD:";
const end = "[EOM]";
return "$beginning$data$end";
}

void printHealthReport(){
print("=======================================");
print("| HEALTH REPORT |");
print("=======================================");
print("ACTIVE CONNNECTIONS: ${_clientConnections.length}");
for(Socket client in _clientConnections){
print("Client ${safeGetClientAddress(client)} ${_connectionHealth[client]}");
}
print("");
print("TOTAL CONNECTIONS: ${_connectionHealth.keys.length}");
print("HEALTH DATA: ");
for (ConnectionHealth data in _connectionHealth.values){
print(data);
}
}

String safeGetClientAddress(Socket client){
try{
return "Client ${client.remoteAddress}:${client.remotePort}";
} catch (exception) {
return "Closed client: ";
}
}

}

0 comments on commit c61c3be

Please sign in to comment.