2014-05-15 71 views
3

我與澤西上證所的官方文檔服務器端事件不使用SSE

在下面的鏈接,請參閱「14.5.2。異步SSE處理用的EventSource」在給定的樣本例如試圖在澤西島2.8射擊 https://jersey.github.io/documentation/2.8/user-guide.html#example-simple-sse

我的代碼如下

客戶端代碼 -

public class ClientSSEEventManager { 
     public void WaitForEvents() { 
      // Client client = ClientBuilder.newBuilder() 
      // .register(SseFeature.class).build(); 
      // WebTarget target = 
      // client.target("http://localhost:8080/server/events"); 
      // 
      // EventInput eventInput = target.request().get(EventInput.class); 
      // while (!eventInput.isClosed()) { 
      // final InboundEvent inboundEvent = eventInput.read(); 
      // if (inboundEvent == null) { 
      // // connection has been closed 
      // break; 
      // } 
      // System.out.println(inboundEvent.getName() + "; " 
      // + inboundEvent.readData(String.class)); 
      // } 

      Client client = ClientBuilder.newBuilder().register(SseFeature.class) 
        .build(); 
      WebTarget target = client.target("http://localhost:8080/server/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, "message-to-client"); 
      eventSource.open(); 
     } 
    } 

public class MyApplication extends ResourceConfig { 
    public MyApplication(){ 
    super(ClientSSEEventManager.class, SseFeature.class); 
    } 
// Set<Class<?>> classes = new HashSet<Class<?>>() { 
//   /** 
//  * 
//  */ 
//  private static final long serialVersionUID = 1L; 
// 
//   { add(ClientSSEEventManager.class); 
//   }}; 
// 
//  @Override 
//  public Set<Class<?>> getClasses() { 
//   return classes; 
//  } 

} 
中的一個

然後操作方法,我只是初始化事件監聽如下

//Start listening to event from server 
    ClientSSEEventManager clientSSEEventManager = new      ClientSSEEventManager(); 
clientSSEEventManager.WaitForEvents(); 
/// 

客戶的web.xml已經INIT-PARAM如下

<init-param> 
    <param-name>javax.ws.rs.Application</param-name> 
    <param-value>com.framework.MyApplication</param-value> 
</init-param> 

服務器代碼 -

@Path("events") 
public class ServerSSEServerEventManager { 
    @GET 
    @Produces(SseFeature.SERVER_SENT_EVENTS) 
    public EventOutput getNotificationEvents(){ 
     final EventOutput eventOutput = new EventOutput(); 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         for (int i = 0; i < 10; i++) { 
          // ... code that waits 1 second 
          final OutboundEvent.Builder eventBuilder 
          = new OutboundEvent.Builder(); 
          eventBuilder.name("message-to-client"); 
          eventBuilder.data(String.class, 
           "Hello world " + i + "!"); 
          final OutboundEvent event = eventBuilder.build(); 
          eventOutput.write(event); 
         } 
        } catch (IOException e) { 
         throw new RuntimeException(
          "Error when writing the event.", e); 
        } finally { 
         try { 
          eventOutput.close(); 
         } catch (IOException ioClose) { 
          throw new RuntimeException(
           "Error when closing the event output.", ioClose); 
         } 
        } 
       } 
      }).start(); 
      return eventOutput; 
    } 
} 

在客戶期望的輸出方如下

message-to-client; Hello world 0! 
message-to-client; Hello world 1! 
message-to-client; Hello world 2! 
message-to-client; Hello world 3! 
message-to-client; Hello world 4! 
message-to-client; Hello world 5! 
message-to-client; Hello world 6! 
message-to-client; Hello world 7! 
message-to-client; Hello world 8! 
message-to-client; Hello world 9! 

但客戶端沒有打印任何東西。 我在這裏錯過了什麼嗎? 我有疑問,客戶端。目標,它應該有「http://:8080 /服務器/事件」?或者它應該只是「http://:8080/events」

+0

你的服務器的URL是依賴於應用程序的'語境Path'。如果你部署爲'server',那麼你的路徑應該是'http:// localhost:8080/server/events'。我會在服務器端添加一些日誌記錄,並將Jackson日誌過濾器添加到客戶端client.register(新的LoggingFilter(LOG,true));'這樣你就可以看到你的客戶端正在發送/接收什麼。 – Baldy

+0

如果我在http:// /server/events中直接在瀏覽器中打開url,則會調用服務器端getNotificationEvents方法。但如果我通過運行上面的代碼中顯示的客戶端應用程序來完成相同的事情,服務器端getNotificationEvents不會被調用。 – Sadanand

+0

好吧,看着你的客戶端代碼,你正在設置事件處理程序,但你永遠不會發出你的GET請求。 – Baldy

回答

1

SSE最後對我很好。 有幾件事情,我們需要做的

  1. SSE聽者泉

    @Singleton 
        @Path("/events") 
        public class NotificationHandler { 
         @Path("/register/{userName}") 
        @Produces(SseFeature.SERVER_SENT_EVENTS) 
        @GET 
        public @ResponseBody EventOutput registerForAnEventSummary(
          @PathParam("userName") String userName) { 
         } 
        } 
    
  2. ,呼叫服務,撥打電話通知所有客戶

    PostMethod postMethod = null; 
         postMethod = new PostMethod(
           resourceBundle.getString("localhost:8080") 
             + resourceBundle.getString("applicationnotifier") 
             + resourceBundle 
               .getString("sse/events/broadcast/")); 
    
  3. 廣播公司

    @Path("/broadcast") 
        @POST 
        @Produces(MediaType.TEXT_PLAIN) 
        @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
        public String broadcastNotifications(@FormParam("message") String message) { } 
    
  4. 使用Javascript - 聽所有SSE事件通過註冊

    var notificationBaseURL = ""; //The URL Where your services are hosted 
    function listenAllEvents() { 
        if ((EventSource) !== "undefined") { 
    
        var source = new EventSource(
        notificationBaseURL+"applicationnotifier/sse/events/register/"+loggedInUserName); 
        source.onmessage = notifyEvent; 
    } else { 
        console.log("Sorry no event data sent - "); 
        } 
    } 
    
    function notifyEvent(event) { 
        var responseJson = JSON.parse(event.data); 
        alert("... Notification Received ..."); 
    } 
    
相關問題