Angular 2 spring boot server side events

前端 未结 4 634
囚心锁ツ
囚心锁ツ 2020-12-05 03:44

Can somebody please provide me an example for spring boot server side events?

Basically I need to push server side events to browser. I\'m using angular 2 and sprin

相关标签:
4条回答
  • 2020-12-05 03:45

    Now with Spring Webflux is easier to accomplish that task, just using MediaTypes like:

        @GetMapping(value = "/queue/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
        public Flux<EventNotification> streamEvents() {
            return managerService.streamEvents();
        }
    

    So you can create architectures like:

    You can check a working implementation in https://github.com/htenjo/vqueue also with an RSocket example.

    0 讨论(0)
  • 2020-12-05 03:49

    No one answered, so answering my own question.

    Have a Spring Rest controller

    SseController.java

    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    @RestController
    public class SSEController {
    
        public static final List<SseEmitter> emitters = Collections.synchronizedList( new ArrayList<>());
    
        @RequestMapping(path = "/stream", method = RequestMethod.GET)
        public SseEmitter stream() throws IOException {
    
            SseEmitter emitter = new SseEmitter();
    
            emitters.add(emitter);
            emitter.onCompletion(() -> emitters.remove(emitter));
    
            return emitter;
        }
    }
    

    ServiceClass.java

    public void sendSseEventsToUI(Notification notification) { //your model class
            List<SseEmitter> sseEmitterListToRemove = new ArrayList<>();
            SSEController.emitters.forEach((SseEmitter emitter) -> {
                try {
                    emitter.send(notification, MediaType.APPLICATION_JSON);
                } catch (IOException e) {
                    emitter.complete();
                    sseEmitterListToRemove.add(emitter);
                    e.printStackTrace();
                }
            });
            SSEController.emitters.removeAll(sseEmitterListToRemove);
        }
    

    finally in Angular2 component do this

    notification.component.ts

    import {Component, OnInit} from '@angular/core';
    
    declare let EventSource:any;
    
    @Component({
        selector: 'notification-cmp',
        templateUrl: 'notification.component.html'  
    })
    
    export class NotificationComponent implements OnInit {
       connect(): void {
            let source = new EventSource('http://localhost:8080/stream');
            source.addEventListener('message', message => {
                let n: Notification; //need to have this Notification model class in angular2
                n = JSON.parse(message.data);
                console.log(message.data); 
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-05 03:58

    The above answer was a great help.

    And..

    To receive actual data pushed..

    the code should be

    source.onmessage = (message)=>{
       let n:Notification = JSON.parse(message.data);
    }
    
    
    source.addEventListener('message', message => {
    // There is no data property available on 'message' here
       let n: Notification; 
       n = JSON.parse(message.data);
       console.log(message.data); 
    });
    
    0 讨论(0)
  • 2020-12-05 04:02

    The Answer from Pratap A.K is great. But to keep it a little bit cleaner, you shoud create a NotificationService which implements a Interface. Like this:

    NotificationServiceImpl.java

    public class NotificationServiceImpl implements NotificationService {
    
    public static final List<SseEmitter> emitters = Collections.synchronizedList(new ArrayList<>());
    
    @Override
    public SseEmitter initSseEmitters() {
    
        SseEmitter emitter = new SseEmitter();
        emitters.add(emitter);
        emitter.onCompletion(() -> emitters.remove(emitter));
    
        return emitter;
    }
    
    @Override
    public void sendSseEventsToUI(WebSource notification) {
        List<SseEmitter> sseEmitterListToRemove = new ArrayList<>();
        this.emitters.forEach((SseEmitter emitter) -> {
            try {
                emitter.send(notification, MediaType.APPLICATION_JSON);
            } catch (IOException e) {
                emitter.complete();
                sseEmitterListToRemove.add(emitter);
                e.printStackTrace();
            }
        });
        this.emitters.removeAll(sseEmitterListToRemove);
      }
    }
    

    NotificationService.java

    public interface NotificationService {
    
    public SseEmitter initSseEmitters();
    public void sendSseEventsToUI(WebSource notification);
    
    }
    

    SSEController.java

    @RestController
    @RequestMapping("/mystream")
    public class SSEController {
    
    @Autowired
    NotificationServiceImpl INotificationServiceImpl;
    
    @CrossOrigin
    @RequestMapping(path = "/streamsource", method = RequestMethod.GET)
    public SseEmitter stream() throws IOException {
    
        return INotificationServiceImpl.initSseEmitters();
      }
    }
    

    Best regards

    0 讨论(0)
提交回复
热议问题