/// <summary> /// Initialize and start the server. /// </summary> public Server(Game game, int capacity) { maxClients = capacity; handlers = new ServerHandler[capacity]; for (int i = 0; i < capacity; i++) { handlers[i] = new ServerHandler(); } this.game = game; Trace.TraceInformation("Server initialized with capacity {0}", capacity); }
/// <summary> /// Initialize and start the server. /// </summary> public Server(Game game, int capacity, IPAddress address) { ipAddress = address; IPEndPoint ep = new IPEndPoint(ipAddress, 0); listener = new TcpListener(ep); listener.Start(); ipPort = ((IPEndPoint)listener.LocalEndpoint).Port; maxClients = capacity; handlers = new ServerHandler[capacity]; for (int i = 0; i < capacity; i++) { handlers[i] = new ServerHandler(); } this.game = game; Trace.TraceInformation("Server initialized with capacity {0}", capacity); }
private void ServerThread(ServerHandler handler) { ItemReceiver r = new ItemReceiver(handler.stream); game.RegisterCurrentThread(); while (true) { object o; do { o = r.Receive(); if (o == null) return; } while (HandleInterrupt(o)); handler.semAccess.WaitOne(); handler.queueIn.Enqueue(o); handler.semAccess.Release(1); handler.semIn.Release(1); } }
private void ClientThread(ServerHandler handler) { ItemSender r = new ItemSender(handler.stream); game.RegisterCurrentThread(); while (true) { handler.semOut.WaitOne(); object o; handler.semAccess.WaitOne(); o = handler.queueOut.Dequeue(); handler.semAccess.Release(1); if (o is FlushObject) { r.Flush(); } else if (!r.Send(o)) { Trace.TraceError("Network failure @ send"); } } }
private void ServerThread(ServerHandler handler) { game.RegisterCurrentThread(); while (true) { object o; if (handler.disconnected) Thread.Sleep(1000); lock (handler.receiver) { do { o = handler.receiver.Receive(); if (o == null) handler.disconnected = true; } while (HandleInterrupt(o)); } if (o != null) { lock (handler.queueIn) { handler.queueIn.Enqueue(o); } handler.semIn.Release(1); } } }
private void ClientThread(ServerHandler handler) { game.RegisterCurrentThread(); while (true) { handler.semOut.WaitOne(); object o; lock (handler.queueOut) { o = handler.queueOut.Dequeue(); } lock (handler.sender) { if (o is FlushObject) { handler.sender.Flush(); } else if (o is TerminationObject) { handler.sender.Flush(); return; } else if (!handler.sender.Send(o)) { Trace.TraceError("Network failure @ send"); } } } }
/// <summary> /// Ready the server. Block if require more clients to connect. /// </summary> public void Start() { Trace.TraceInformation("Listener Started on {0} : {1}", ipAddress.ToString(), IpPort); int To = 6000; game.Settings.Accounts = new List<Account>(); for (int i = 0; i < numberOfGamers; i++) { handlers[i].game = game; handlers[i].client = listener.AcceptTcpClient(); Trace.TraceInformation("Client connected"); handlers[i].stream = handlers[i].client.GetStream(); handlers[i].stream.ReadTimeout = To; if (To >= 2000) To -= 1000; if (game.Configuration != null) { object item; try { item = (new ItemReceiver(handlers[i].stream)).Receive(); } catch (Exception) { item = null; } if (!(item is LoginToken) || !game.Configuration.AccountIds.Any(id => id.TokenString == ((LoginToken)item).TokenString)) { handlers[i].client.Close(); i--; continue; } int index; for (index = 0; index < game.Configuration.AccountIds.Count; index++) { if (game.Configuration.AccountIds[index].TokenString == ((LoginToken)item).TokenString) { game.Settings.Accounts.Add(game.Configuration.Accounts[index]); } } } handlers[i].stream.ReadTimeout = Timeout.Infinite; handlers[i].stream = new RecordTakingOutputStream(handlers[i].stream); handlers[i].sender = new ItemSender(handlers[i].stream); handlers[i].receiver = new ItemReceiver(handlers[i].stream); handlers[i].threadServer = new Thread((ParameterizedThreadStart)((o) => { ServerThread(handlers[(int)o]); })) { IsBackground = true }; handlers[i].threadServer.Start(i); handlers[i].threadClient = new Thread((ParameterizedThreadStart)((o) => { ClientThread(handlers[(int)o]); })) { IsBackground = true }; handlers[i].threadClient.Start(i); } var spectatorHandler = new ServerHandler(); spectatorHandler.game = game; spectatorHandler.stream = new ReplaySplitterStream(); spectatorHandler.receiver = new ItemReceiver(spectatorHandler.stream); spectatorHandler.sender = new ItemSender(spectatorHandler.stream); spectatorHandler.disconnected = true; spectatorHandler.threadServer = null; spectatorHandler.threadClient = new Thread((ParameterizedThreadStart)((o) => { ClientThread(handlers[(int)o]); })) { IsBackground = true }; handlers.Add(spectatorHandler); spectatorHandler.threadClient.Start(handlers.Count - 1); Trace.TraceInformation("Server ready"); reconnectThread = new Thread(ReconnectionListener) { IsBackground = true }; reconnectThread.Start(); }