2017-04-26 3 views
0

Ich habe eine rudimentäre Java-Anwendung geschrieben, um SSE (server-sent events) zu verwenden, die von einem Node.js-Server mit dem Jersey SSE-Client gestreamt wurden. Ich kann die Ereignisse jedoch nicht empfangen. Um zu überprüfen, die Server-Komponente wie erwartet funktioniert, ich habe die curl wie folgt verwendet:Jersey SSE-Client empfängt keine Ereignisse

curl -v -H "Accept: text/event-stream" http://localhost:8080/events/ 

ich die folgende Antwort erhalten:

* Trying ::1... 
* Connected to localhost (::1) port 8080 (#0) 
> GET /events/ HTTP/1.1 
> Host: localhost:8080 
> User-Agent: curl/7.43.0 
> Accept: text/event-stream 
> 
< HTTP/1.1 200 OK 
< X-Powered-By: Express 
< Content-Type: text/event-stream 
< Cache-Control: no-cache 
< Connection: keep-alive 
< Date: Wed, 26 Apr 2017 17:12:00 GMT 
< Transfer-Encoding: chunked 
< 

event: ping 
data: 0.6637400726922664 

event: ping 
data: 0.8538157046725585 

Der Code für mein SSE-Client in Java wird wie folgt (Java 8, Jersey-Client 1.19.3, Jersey Medien SSE 2.25.1):

import org.glassfish.jersey.media.sse.EventListener; 
import org.glassfish.jersey.media.sse.EventSource; 
import org.glassfish.jersey.media.sse.InboundEvent; 
import org.glassfish.jersey.media.sse.SseFeature; 

import javax.ws.rs.client.Client; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.client.WebTarget; 

public class NodeCaptureSSE { 

    public static void main(String[] args) { 

    Client client = ClientBuilder.newBuilder().register(SseFeature.class).build(); 
    WebTarget target = client.target("http://localhost:8080/events/"); 
    EventSource eventSource = EventSource.target(target).build(); 
    EventListener listener = new EventListener() { 
     @Override 
     public void onEvent(InboundEvent inboundEvent) { 
      System.out.println(inboundEvent.getName() + "; " + inboundEvent.readData(String.class)); 
     } 
    }; 
    eventSource.register(listener, "ping"); 
    eventSource.open(); 
    System.out.println("Connected to SSE source..."); 
    try { 
     Thread.sleep(25_000); 
    } 
    catch (InterruptedException ie) { 
     System.err.println("Exception: " + ie.getMessage()); 
    } 
    eventSource.close(); 
    System.out.println("Closed connection to SSE source"); 
    } 
} 

der einzige Ausgang ich auf dem Bildschirm zu sehen ist:

Connected to SSE source... 

gefolgt von einem Ausgang, nach 25 Sekunden. Da der Server benannte Ereignisse ("ping") streamt, habe ich dies beim Registrieren des Listeners für die Ereignisquelle angegeben. Das Auslassen des zweiten Parameters an die eventSource.register(...); hat nichts getan, obwohl ich das nicht erwartet habe. Ich habe auch die Endung / in der URL entfernt, aber das ergibt einen 404 Not Found (wie erwartet). Ich hoffe, dass ich irgendwelche Hinweise in die richtige Richtung bekomme.

Antwort

2

Ihr Code funktionierte gut für mich. In der Tat habe ich verzweifelt nach diesem Code gesucht, also danke^_^hahaha. Wie auch immer, ich habe einen SSE-Ereignisstrom, der Zeitereignisse ausgibt, und hier sieht meine Ausgabe mit Ihrem Code aus (ich habe den Ping zu Zeitereignis geändert, um ihn an meinen Server anzuhängen).

Connected to SSE source... 
time-event; Time is Thu Jul 20 10:10:37 CDT 2017 
time-event; Time is Thu Jul 20 10:10:41 CDT 2017 

Das Problem ist höchstwahrscheinlich mit Ihrem Event-Stream und der URL, die Sie auf ihn zu verweisen verwenden, nicht mit Ihrem clientseitigen Java-Code. Eine andere Sache, die mir aufgefallen ist, ist, dass ich in Ihrem Curl-Befehl dort keine Charset-Spezifikation sehe. Stellen Sie sicher, dass Ihr Zeichensatz auf UTF-8 eingestellt ist. So sieht meine cmd-Ausgabe aus: enter image description here

Hier ist der Code, den ich verwende, um den Stream zu erzeugen.

import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.xml.ws.http.HTTPException; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.net.PasswordAuthentication; 
import java.util.Calendar; 



    @SuppressWarnings("java.io.IOException") 
    @WebServlet("/SSEServlet") 
    public class SSEServlet extends HttpServlet { 
     private static final long serialVersionUID = 1L; 
     private boolean cancel; 

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { 

      System.out.println("You just entered the doGetMethod"); 
      response.setContentType("text/event-stream"); 
      response.setCharacterEncoding("UTF-8"); 
      PrintWriter printWriter = null; 
      response.getBufferSize(); 


      while(true){ 
       try{ 
        System.out.println("You just entered the while loop"); 
        double randomNumber = Math.random()*10000; 
        printWriter = response.getWriter(); 

        printWriter.print("event: time-event" + "\n"); 
        printWriter.print("data: " + "Time is " + Calendar.getInstance().getTime() + "\n\n"); 
        response.flushBuffer(); 
        Thread.sleep((long)randomNumber); 

       } catch (IOException | InterruptedException e){ 
        e.printStackTrace(); 
        break; 
       } 
      } 
      System.out.println("Connection was aborted"); 
     } 
    } 
+1

Gibt es eine Möglichkeit, die Verbindung für längere Zeit geöffnet zu halten ?, wird Jersey Sse Client wie ein Browser funktionieren? –

Verwandte Themen