comparison src/goodjava/webserver/ServerSentEvents.java @ 1738:9713f7fd50b3

server-sent events
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 03 Nov 2022 19:23:53 -0600
parents
children c9c974817d0c
comparison
equal deleted inserted replaced
1737:6c9aea554691 1738:9713f7fd50b3
1 package goodjava.webserver;
2
3 import java.io.Writer;
4 import java.io.OutputStreamWriter;
5 import java.io.BufferedWriter;
6 import java.io.IOException;
7 import java.net.Socket;
8 import java.util.List;
9 import java.util.ArrayList;
10 import java.util.Map;
11 import java.util.HashMap;
12 import java.util.Collections;
13 import java.util.Iterator;
14
15
16 public class ServerSentEvents {
17
18 private static class Con {
19 final Socket socket;
20 final Writer writer;
21
22 Con(Socket socket) throws IOException {
23 this.socket = socket;
24 this.writer = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream(), "UTF-8" ) );
25 }
26 }
27
28 private static class EventHandler {
29 private final List<Con> cons = new ArrayList<Con>();
30
31 synchronized void add(Con con) {
32 cons.add(con);
33 }
34
35 synchronized void write( String url, String content ) {
36 Iterator<Con> iter = cons.iterator();
37 while( iter.hasNext() ) {
38 Con con = iter.next();
39 Writer writer = con.writer;
40 try {
41 writer.write(content);
42 writer.write("\n\n");
43 writer.flush();
44 } catch(IOException e) {
45 iter.remove();
46 }
47 }
48 if( cons.isEmpty() )
49 map.remove(url);
50 }
51 }
52
53 private static final Map<String,EventHandler> map
54 = Collections.synchronizedMap(new HashMap<String,EventHandler>());
55
56 static void add(Socket socket,Request request) throws IOException {
57 Con con = new Con(socket);
58
59 Writer writer = con.writer;
60 writer.write("HTTP/1.1 200 OK\r\n");
61 writer.write("Access-Control-Allow-Origin: *\r\n");
62 writer.write("Cache-Control: no-cache\r\n");
63 writer.write("Content-Type: text/event-stream\r\n");
64 writer.write("\r\n");
65 writer.flush();
66
67 String url = request.url();
68 EventHandler handler;
69 synchronized(map) {
70 handler = map.get(url);
71 if( handler==null ) {
72 handler = new EventHandler();
73 map.put(url,handler);
74 }
75 }
76 handler.add(con);
77 }
78
79 public static void write( String url, String content ) {
80 EventHandler handler = map.get(url);
81 if( handler != null )
82 handler.write(url,content);
83 }
84
85 public static String toData(String message) {
86 if( message.endsWith("\n") )
87 message = message.substring( 0, message.length() - 1 );
88 return "data: " + message.replace( "\n", "\ndata: " ) + "\n";
89 }
90
91 public static void writeMessage( String url, String message ) {
92 write( url, toData(message) );
93 }
94
95 private ServerSentEvents() {} // never
96 }