首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jersey SSE客户端未接收事件

Jersey SSE客户端未接收事件
EN

Stack Overflow用户
提问于 2017-04-27 01:33:46
回答 2查看 2.4K关注 0票数 1

我已经编写了一个基本的Java应用程序,使用Jersey SSE客户机使用从Node.js服务器流传输的SSE (服务器发送的事件)。但是,我无法接收事件。为了验证服务器组件是否按预期工作,我按如下方式使用了curl

代码语言:javascript
复制
curl -v -H "Accept: text/event-stream" http://localhost:8080/events/

我得到以下响应:

代码语言:javascript
复制
*   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

我的SSE客户端的Java代码如下(Java 8,Jersey client 1.19.3,Jersey Media SSE 2.25.1):

代码语言:javascript
复制
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");
  }
}

我在屏幕上看到的唯一输出是:

代码语言:javascript
复制
Connected to SSE source...

25秒后退出。由于服务器正在流式传输命名事件("ping"),因此我在将侦听器注册到事件源时指定了这一点。省略eventSource.register(...);的第二个参数没有任何作用,尽管我并不期望它会这样做。我还删除了URL中的结尾/,但这会生成一个404 Not Found (不出所料)。我希望在正确的方向上得到任何指示。

EN

回答 2

Stack Overflow用户

发布于 2017-07-20 23:29:27

你的代码对我来说运行得很好。事实上,我一直在拼命寻找这段代码,所以谢谢^_^,哈哈哈。无论如何,我有一个输出时间事件的SSE事件流,下面是我的输出在您的代码中的样子(我将ping更改为time-event以附加到我的服务器)。

代码语言:javascript
复制
 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

问题很可能出在你的事件流和你用来指向它的URL上,而不是你的客户端java代码。我注意到的另一件事是,在curl命令中,我没有看到其中的字符集规范。确保您的字符集设置为UTF-8。下面是我的cmd输出:

下面是我用来生成流的代码。

代码语言:javascript
复制
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");
        }
    }
票数 5
EN

Stack Overflow用户

发布于 2018-07-19 15:50:48

如果您的应用程序是Spring Boot应用程序,则存在与Jersey的兼容性问题。您需要添加另一个依赖org.glassfish.jersey.inject:jersey-hk2:2.26来解决此问题。

请参阅https://github.com/bmuschko/gradle-docker-plugin/issues/534 https://github.com/jersey/jersey/issues/3664

这似乎不仅仅与Gradle有关。在我的例子中,我的项目是Maven和Spring Boot应用程序,添加此依赖项后,我立即收到事件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43640962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档