72 lines
2.4 KiB
Java
72 lines
2.4 KiB
Java
package com.ankurm.ssews;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.net.Socket;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* A raw-socket SSE client.
|
|
*
|
|
* <p>Deliberately not an HTTP client library: the article quotes the bytes on the wire, and any
|
|
* client that parses events for you hides exactly the thing being shown. It also lets a test
|
|
* abandon the socket mid-stream, which is how the disconnect case is reproduced.
|
|
*/
|
|
final class SseClient implements AutoCloseable {
|
|
|
|
private final Socket socket;
|
|
private final BufferedReader reader;
|
|
private final List<String> lines = new ArrayList<>();
|
|
|
|
SseClient(int port, String path) throws Exception {
|
|
this(port, path, null);
|
|
}
|
|
|
|
SseClient(int port, String path, String lastEventId) throws Exception {
|
|
this.socket = new Socket("127.0.0.1", port);
|
|
this.socket.setSoTimeout(15_000);
|
|
StringBuilder req = new StringBuilder()
|
|
.append("GET ").append(path).append(" HTTP/1.1\r\n")
|
|
.append("Host: 127.0.0.1:").append(port).append("\r\n")
|
|
.append("Accept: text/event-stream\r\n");
|
|
if (lastEventId != null) {
|
|
req.append("Last-Event-ID: ").append(lastEventId).append("\r\n");
|
|
}
|
|
req.append("Connection: close\r\n\r\n");
|
|
OutputStream out = socket.getOutputStream();
|
|
out.write(req.toString().getBytes(StandardCharsets.UTF_8));
|
|
out.flush();
|
|
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
|
|
}
|
|
|
|
/** Read until the stream closes or {@code max} lines have arrived. Records everything. */
|
|
List<String> read(int max) throws Exception {
|
|
String line;
|
|
while (lines.size() < max && (line = reader.readLine()) != null) {
|
|
lines.add(line);
|
|
}
|
|
return List.copyOf(lines);
|
|
}
|
|
|
|
/** Read everything until the server closes the connection. */
|
|
List<String> readToEnd() throws Exception {
|
|
String line;
|
|
while ((line = reader.readLine()) != null) {
|
|
lines.add(line);
|
|
}
|
|
return List.copyOf(lines);
|
|
}
|
|
|
|
List<String> lines() {
|
|
return List.copyOf(lines);
|
|
}
|
|
|
|
@Override
|
|
public void close() throws Exception {
|
|
socket.close();
|
|
}
|
|
}
|