2015-01-19 3 views
2

Я не могу понять, как уведомить мой класс сервера о том, что соединение было потеряно. Мой код сервера:Не удается правильно отслеживать подключенных клиентов java

public class Server { 

    static int port = 4444; 
    static boolean listening = true; 
    static ArrayList<Thread>Clients = new ArrayList<Thread>(); 
    static MatchMaker arena; 

    public static void main(String[] args) { 
     Initialize(); 
     Thread startConnections = new Thread(run()); 
     startConnections.start(); 
    } 

    private static Runnable run(){ 
     System.out.println("(" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + ") Started listening on port: " + port); 
     try(ServerSocket socket = new ServerSocket(port)){ 
      while(listening){ 
       if(Clients.size() <= 4){ 
        Socket clientSocket = socket.accept(); 

        MultiThread connection = new MultiThread(clientSocket, arena,); 
        Clients.add(connection); 

        System.out.println("Client connected from " + clientSocket.getRemoteSocketAddress() + " Assigned ID: " + connection.getId()); 
        System.out.println("Currently connected clients(" + Clients.size() + "): "); 
        for(int i = 0; i < Clients.size(); i++) 
         System.out.println(" - " + Clients.get(i).getId()); 
        connection.start(); 
       } 
      } 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    private static void Initialize(){ 
     arena = new MatchMaker(); 
    } 

} 

Проблема здесь состоит в том, что, поскольку этот класс отслеживает подключенных клиентов, я хочу, чтобы это заметить, когда клиент потерял соединение. Класс MultiThread уже имеет функциональный способ обнаружения клиентов, потерявших соединение, однако я не знаю, как передать эту информацию обратно в класс Server. Я пробовал передать класс сервера MultiThread в качестве параметра, но он сказал, что я не могу использовать «это» статическим образом.

+0

Btw, в 'main' ваш код не открыт или прорвался. Вы можете просто вызвать 'run()' вместо этого кода. –

+0

И нет кода в 'Server', который должен обрабатывать уведомления об отключении. –

ответ

1

Вы можете держать их в синхронной карте как:

Map<Integer, ClientObject> connectedClients = new HashMap<Integer, ClientObject>(); //key integer will be the client id 

Другое предложение:

Map<String, ClientObject> connectedClients = new HashMap<String, ClientObject>(); //key String will be the client IP&userName (you decide) 
+0

Как я могу получить доступ к карте в другом классе? – user3546193

+0

вы можете создать синглтон, который поможет вам вставить/получить данные из этого. синглтон будет управлять всеми подключенными вами клиентами – roeygol

0

Кулак всего использование потокобезопасной сбора для контроля соединения клиента так заменить следующие ArrayList клиентов = новый ArrayList(); с ConcurrentLinkedQueue Clients = new ConcurrentLinkedQueue(); Но ваша проблема заключается в том, что вы пытаетесь использовать ограниченный ресурс в потоковом безопасном режиме, поэтому лучшим вариантом будет использование Семафора. Я немного перечислил ваш класс, чтобы дать идею. Надеюсь, это поможет. Plz внимательно посмотрите на «SERVER_INSTANCE».

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.concurrent.ConcurrentLinkedQueue; 
import java.util.concurrent.Semaphore; 

public class Server { 
    private final int MAX_AVAILABLE = 4; 
    public final Semaphore SERVER_INSTANCE = new Semaphore(MAX_AVAILABLE, true); 

    static int port = 4444; 
    static volatile boolean listening = true; 
    static MatchMaker arena; 

    public static void main(String[] args) { 
     Initialize(); 
     Thread startConnections = new Thread(run()); 
     startConnections.start(); 
    } 

    private static void Initialize() { 
     //do somthing 
    } 

    private static Runnable run(){ 
     System.out.println("(" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + ") Started listening on port: " + port); 
     ServerSocket socket = null; 
     while(listening){ 
      try { 
       socket = new ServerSocket(port); 
       try { 
        SERVER_INSTANCE.acquire(); 
         Socket clientSocket = socket.accept(); 
         MultiThread connection = new MultiThread(clientSocket, arena, SERVER_INSTANCE); 

       } catch (InterruptedException e) { 
        e.printStackTrace();   
       } 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 

     } 
     return null; 
    } 

    static class MultiThread implements Runnable{ 
     Semaphore serverInstance ; 
     public MultiThread(Socket clientSocket, MatchMaker arena, Semaphore serverInstance) { 
      serverInstance = serverInstance; 
     } 

     @Override 
     public void run() { 
      try { 
       serverInstance.acquire(); 
       //Do your work here 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      }finally { 
       serverInstance.release(); 
      } 
     } 
    } 

     class MatchMaker { 

     } 
} 
Смежные вопросы