当前位置: 首页 > 知识库问答 >
问题:

使用SSE在Jersey 2.8中未触发服务器端事件

隆功
2023-03-14

我正在尝试Jersey SSE官方文档中给出的示例

请参阅以下链接中的“14.5.2.使用EventSource的异步SSE处理”https://jersey.github.io/documentation/2.8/user-guide.html#example-简单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参数如下

<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!

但是客户端没有打印任何东西。我在这里错过了什么吗?我有一个疑问,客户端。目标,它应该有“超文本传输协议://: 8080/服务器/事件”?或者它应该只是“超文本传输协议://: 8080/事件”

共有1个答案

佘缪文
2023-03-14

上交所最终对我很好。有几件事我们需要做

>

  • Springs中的SSE监听器

      @Singleton
         @Path("/events")
         public class NotificationHandler {
             @Path("/register/{userName}")
         @Produces(SseFeature.SERVER_SENT_EVENTS)
         @GET
         public @ResponseBody EventOutput registerForAnEventSummary(
                @PathParam("userName") String userName) {
            }
         }
    

    调用调用以通知所有客户端的服务

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

    一个广播员

     @Path("/broadcast")
        @POST
         @Produces(MediaType.TEXT_PLAIN)
         @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
        public String broadcastNotifications(@FormParam("message") String message) { }
    

    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 ...");
     }
    

  •  类似资料:
    • 我有一个ASP。net core 3.1服务器项目,它有一个非常简单的API发送单向服务器发送事件(SSE),如下所示: 现在,我想通过C#UWP客户端接收这些事件。很遗憾,我只收到第一个事件: 如何在UWP中创建行为以始终监听该连接并接收我可以进一步处理的事件?

    • 我无法理解HTML5s服务器发送的事件是否真的适合ReST体系结构。我知道并非HTML5/HTTP的所有方面都需要适合ReST架构。但我想从专家那里知道HTTP的哪一半是SSE(ReSTful的一半还是另一半!)。 一种观点是它是ReSTful的,因为客户端向服务器发出了一个“初始”HTTP GET请求,其余的只能看作是不同内容类型的部分内容响应(“文本/事件流”) 发送的请求不知道有多少响应将作

    • 使用系统将“服务器发送事件(SSE)样式”事件流式传输到F#中的前端的轻量级方式是什么。网Http库?我了解事件流格式(例如,这个PHP示例代码),但我正在寻求一些指导,以便在服务器端F#应用程序(我在.Net Framework 4.8上)中实现流部分。

    • 我已经在Java服务器中设置了SSE(服务器发送事件)。客户端构建在VueJS上,并使用EventSource包从服务器接收事件。我正在使用EventSourcePolyfill npm包https://www.npmjs.com/package/event-source-polyfill在客户端上。这个包允许我们在请求中发送授权头(针对我们的安全方案)。 客户端向我们的SSE服务发送请求并接收一

    • 我是泽西岛使用SSE的新手,有以下情况。 我有一个JAXB注释类,它表示Raspberry Pi的I/O并对其起作用(类GpioSymation)。 客户端类通过返回类的XML对象表示的方法getUpdate()访问I/O的状态。 使用getUpdate()的客户端是HomeResource类,方法getPiStatusStream()。这是一个JAX-RS注释方法,并提供远程客户端服务器发送的事

    • 您好,我正在React中开发一个web应用程序,它使用Nginx从Express服务器接收SSE数据。 JS服务器 索引:JS const events=新事件源('https://api.myDomain.com/events', ); axios。post(<代码>https://api.myDomain.com/addCart,{客户端:this.state.clientId,购物车:car