markk: Mocken eines ServerSockets und clients

Beitrag lesen

Moin,

ich benötige einen ServerSocket-Mock und einen Client, der in definierten Abständen Daten an das Socket liefert.

Ich habe bereits etliche Beispiele, die ich finden konnte, ausprobiert. Leider ohne Erfolg.

Den Code habe ich bereits in so weit vereinfacht, dass es nur noch eine einfache Main-Class ist.

Mein Ziel

Ich möchte, dass ein Service lediglich MySocketMock.start() aufrufen muss, um einen Mock-Socket zu starten. Diese Klasse/Methdoe soll dazu einen Fake-Client initialisieren, der in einem separaten Thread kontinuierlich Daten an das Socket sendet.

Meine bisherigen Erfolge

  1. Der Server startet fein, blockiert aber den Verlauf der weiteren Anwendung
  2. Der Server failed während er versucht den Socket zu accepten (wahrscheinlich #1)
  3. Der Client wird lediglich einmal aufgerufen, selbst wenn ScheduledExecutorService genutzt wird
  4. Der Client führt gar keine Action aus
  5. Das Gesamtszenario funktioniert, aber eine CPU ist mit 100% ausgelastet (Bsp #2)

Bsp #1

`

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {

public static void main(String[] args) {
    new SocketMock(9988, 2).startSocket();
}

private static class SocketMock {

    private ServerSocket serverSocket;
    private ScheduledExecutorService executor;

    private int port;
    private int interval; // seconds;

    SocketMock(int port, int interval) {
    this.port = port;
    this.interval = interval;
    this.executor = Executors.newScheduledThreadPool(15);
    }

    void startSocket() {
    System.out.println("Starting socket mock");

    final Socket[] clientSocket = new Socket[1];

    Thread serverRunnable = new Thread(() -> {
        try {
        serverSocket = new ServerSocket(port);

        //while (true) {
        System.out.println("Accepting clients..");
        clientSocket[0] = serverSocket.accept();
        System.out.println("Clients accepted.");
        //}
        } catch (IOException e) {
        e.printStackTrace();
        }
        System.out.println("Mock server started");
    });

    // Attach Client
    executor.scheduleAtFixedRate(
        new ClientRunnable(clientSocket[0]),
        1,
        this.interval,
        TimeUnit.SECONDS
    );

    // Start Server
    Thread serverThread = new Thread(serverRunnable);
    serverThread.start();
    }

    private class ClientRunnable implements Runnable {
    Socket clientSocket;

    ClientRunnable(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        System.out.println("Got a client!");
        try {
        OutputStream outputStream = clientSocket.getOutputStream();
        PrintWriter out = new PrintWriter(outputStream);
        out.println("Yeah");
        out.flush();
        } catch (IOException e) {
        e.printStackTrace();
        }
    }
    }
}

}

`

Bsp #2

`

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ElevatorSocketMock {

    private int port;

    public ElevatorSocketMock(int port, int interval) {
        this.port = port;
        this.startServer(interval);
    }

    private void startServer(int interval) {
        final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);

        Runnable serverTask = () -> {
        try {
            ServerSocket serverSocket = new ServerSocket(this.port);
            Logger.log(LogComponent.SOCKET, "Mock server started");
            while (true) {
            Socket clientSocket = serverSocket.accept();
            clientProcessingPool.submit(new ClientTask(clientSocket, interval));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        };

        Thread serverThread = new Thread(serverTask);
        serverThread.start();
    }

    private class ClientTask implements Runnable {

        private final Socket clientSocket;
        private final Integer interval;

        private Random random = new Random();

        private ClientTask(Socket clientSocket, int interval) {
        this.clientSocket = clientSocket;
        this.interval = interval;
        }

        @Override
        public void run() {
        Logger.log(LogComponent.SOCKET, "Got a client!");
        Runnable sendDummyEvent = () -> {

            String eventItem = this.generateRandomEvent();
            String event = this.wrapAsValidEvent(eventItem);

            try {
            OutputStream outputStream = this.clientSocket.getOutputStream();
            PrintWriter out = new PrintWriter(outputStream);
            out.println(event);
            out.flush();
            } catch (IOException e) {
            e.printStackTrace();
            }
        };

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        executor.scheduleAtFixedRate(sendDummyEvent, 1, this.interval, TimeUnit.SECONDS);
        }

        private String wrapAsValidEvent(String eventItem) {
        return eventItem; // CODE CUT
        }

        private String generateRandomEvent() {
        return "foo";  // CODE CUT 
        }

    }

}`

Cheers, markk