public static async Task Main(string[] args) { // Get the IP address to bind to as a command line arguement or default // to 127.0.0.1. var userSuppliedIp = args.Length < 1 ? "127.0.0.1" : args[0]; // Require the IP address be supplied as a command line argument. var localIp = IPAddress.Parse(userSuppliedIp); var localEndPoint = new IPEndPoint(localIp, BspConstants.DefaultPort); // Begin listening for clients attempting to discover the server IP _ = StartUdpListing(localEndPoint); // Create objects used for every connection. var generalLogger = new Logger(Console.Out); var unparser = new MessageUnparser(); var listener = new BspListener(generalLogger); var gameTypeRepo = CreateGameTypeRepository(); var userRepo = CreateUserRepository(); var matchMaker = new MatchMaker(); // The body of this foreach loop is a callback. This body will run for // connection our listener accepts. Here we create objects specific for // each connection. await foreach (var socket in listener.StartListeningAsync(localEndPoint)) { // Create a logger that will log with the client's EndPoint. var logger = new EndPointLogger(Console.Out, socket.RemoteEndPoint); // Create a disconnecter that can clean up a connection. var disconnecter = new ServerDisconnecter(logger, socket, userRepo, matchMaker); // Create a sender for sending messages to the client. var senderHandler = new MultiMessageHandler(); var sender = new BspSender(socket, logger, unparser, senderHandler); // Create a container for this connections state. var container = new ServerNetworkStateContainer(sender, disconnecter, gameTypeRepo, userRepo, matchMaker); // Create a context for our state machine. var context = new NetworkStateContext(container, disconnecter); // Register incoming messages with this context. senderHandler.AddHandler(LoggingMessageHandler.ForSending(logger)); senderHandler.AddHandler(new SentMessageHandler(context)); // Register outgoing messages with this context. var receiverHandler = new MultiMessageHandler(); receiverHandler.AddHandler(LoggingMessageHandler.ForReceiving(logger)); receiverHandler.AddHandler(new ReceiveMessageHandler(context)); // Create a parser for this connection var parser = new MessageParser(receiverHandler, gameTypeRepo); // Begin asynchronously receiving messages var receiver = new BspReceiver(socket, disconnecter, parser, logger); _ = receiver.StartReceivingAsync(); } }
public static async Task Main(string[] args) { // Create a logger var logger = new Logger(Console.Out); // If the user did not supply an IP or hostname, attempt to // discover a server on the same subnet. IPEndPoint endPoint; if (args.Length > 0) { if (IPAddress.TryParse(args[0], out var ip)) { endPoint = new IPEndPoint(ip, BspConstants.DefaultPort); } else { // Maybe the user supplied a hostname not an IP var addresses = Dns.GetHostAddresses(args[0]); if (addresses.Length < 1) { Console.WriteLine("Could not find hostname."); return; } endPoint = new IPEndPoint(addresses.Last(), BspConstants.DefaultPort); } } else { logger.LogInfo("Attempting to discover server end point..."); endPoint = await DiscoverServerEndPoint(BspConstants.DefaultPort); } // Attempt to connect to the server. var unparser = new MessageUnparser(); var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); try { logger.LogInfo($"Attempting to connect to {endPoint}"); socket.Connect(endPoint); } catch (SocketException) { logger.LogError($"Failed to connect to {endPoint}"); } // Create a disconnecter that can clean up a connection. var disconnecter = new ClientDisconnecter(logger, socket); // Create a sender for sending to the server. var senderHandler = new MultiMessageHandler(); var sender = new BspSender(socket, logger, unparser, senderHandler); // Create a prompter to handle user interaction. var prompter = new Prompter(sender); // Create a state machine var container = new ClientNetworkStateContainer(prompter); var context = new NetworkStateContext(container, disconnecter); // Register sending messages with our state machine. senderHandler.AddHandler(LoggingMessageHandler.ForSending(logger)); senderHandler.AddHandler(new SentMessageHandler(context)); // Register receiving messages with our state machine. var receiverHandler = new MultiMessageHandler(); receiverHandler.AddHandler(LoggingMessageHandler.ForReceiving(logger)); receiverHandler.AddHandler(new ReceiveMessageHandler(context)); // Create a parser for our connection with the server var parser = new MessageParser(receiverHandler, new GameTypeRepository()); var receiver = new BspReceiver(socket, disconnecter, parser, logger); // Begin receive messages and start the prompt. var receivingTask = receiver.StartReceivingAsync(); prompter.PromptLogOn(); await receivingTask; }