Mercurial Hosting > luan
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/goodjava/webserver/ServerSentEvents.java Thu Nov 03 19:23:53 2022 -0600 @@ -0,0 +1,96 @@ +package goodjava.webserver; + +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.io.IOException; +import java.net.Socket; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.util.Iterator; + + +public class ServerSentEvents { + + private static class Con { + final Socket socket; + final Writer writer; + + Con(Socket socket) throws IOException { + this.socket = socket; + this.writer = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream(), "UTF-8" ) ); + } + } + + private static class EventHandler { + private final List<Con> cons = new ArrayList<Con>(); + + synchronized void add(Con con) { + cons.add(con); + } + + synchronized void write( String url, String content ) { + Iterator<Con> iter = cons.iterator(); + while( iter.hasNext() ) { + Con con = iter.next(); + Writer writer = con.writer; + try { + writer.write(content); + writer.write("\n\n"); + writer.flush(); + } catch(IOException e) { + iter.remove(); + } + } + if( cons.isEmpty() ) + map.remove(url); + } + } + + private static final Map<String,EventHandler> map + = Collections.synchronizedMap(new HashMap<String,EventHandler>()); + + static void add(Socket socket,Request request) throws IOException { + Con con = new Con(socket); + + Writer writer = con.writer; + writer.write("HTTP/1.1 200 OK\r\n"); + writer.write("Access-Control-Allow-Origin: *\r\n"); + writer.write("Cache-Control: no-cache\r\n"); + writer.write("Content-Type: text/event-stream\r\n"); + writer.write("\r\n"); + writer.flush(); + + String url = request.url(); + EventHandler handler; + synchronized(map) { + handler = map.get(url); + if( handler==null ) { + handler = new EventHandler(); + map.put(url,handler); + } + } + handler.add(con); + } + + public static void write( String url, String content ) { + EventHandler handler = map.get(url); + if( handler != null ) + handler.write(url,content); + } + + public static String toData(String message) { + if( message.endsWith("\n") ) + message = message.substring( 0, message.length() - 1 ); + return "data: " + message.replace( "\n", "\ndata: " ) + "\n"; + } + + public static void writeMessage( String url, String message ) { + write( url, toData(message) ); + } + + private ServerSentEvents() {} // never +}