Last active
April 2, 2019 11:29
-
-
Save thetekst/b32621aedf4e56e7eba29396ac406171 to your computer and use it in GitHub Desktop.
Server Side Events (SSE). Spring Boot 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.tkachenko.app.rest.controller; | |
import lombok.extern.slf4j.Slf4j; | |
import org.springframework.http.MediaType; | |
import org.springframework.web.bind.annotation.CrossOrigin; | |
import org.springframework.web.bind.annotation.DeleteMapping; | |
import org.springframework.web.bind.annotation.GetMapping; | |
import org.springframework.web.bind.annotation.PathVariable; | |
import org.springframework.web.bind.annotation.PostMapping; | |
import org.springframework.web.bind.annotation.RequestBody; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RestController; | |
import reactor.core.publisher.Flux; | |
import reactor.util.function.Tuple2; | |
import ru.tkachenko.app.data.converter.TopicConverter; | |
import ru.tkachenko.app.data.model.db.Topic; | |
import ru.tkachenko.app.rest.model.TopicDto; | |
import ru.tkachenko.app.rest.model.TopicRequest; | |
import java.time.Duration; | |
import java.time.LocalDateTime; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Random; | |
import java.util.stream.Stream; | |
/** | |
* @author d.tkachenko | |
*/ | |
@Slf4j | |
@RestController | |
@RequestMapping(ControllerConstant.V1 + "/topic/futures") | |
public class FuturesTopicController { | |
private final List<Topic> favorites = new ArrayList<>(); | |
private final TopicConverter topicConverter; | |
public FuturesTopicController(final TopicConverter topicConverter) { | |
this.topicConverter = topicConverter; | |
final LocalDateTime now = LocalDateTime.now(); | |
final List<Topic> topics = List.of( | |
new Topic() | |
.setId(1L) | |
.setName("Left") | |
.setCreated(now) | |
.setUpdated(now), | |
new Topic() | |
.setId(2L) | |
.setName("Right") | |
.setCreated(now) | |
.setUpdated(now), | |
new Topic() | |
.setId(3L) | |
.setName("Top") | |
.setCreated(now) | |
.setUpdated(now), | |
new Topic() | |
.setId(4L) | |
.setName("Bottom") | |
.setCreated(now) | |
.setUpdated(now)); | |
favorites.addAll(topics); | |
} | |
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE) | |
@CrossOrigin | |
public Flux<TopicDto> get() { | |
Flux<Long> interval = Flux.interval(Duration.ofSeconds(5)); | |
interval.subscribe((i) -> favorites.forEach(topic -> topic.setUpdated(LocalDateTime.now()))); | |
Flux<TopicDto> stockTransactionFlux = Flux.fromStream(Stream.generate(() -> { | |
final Topic randomTopic = getRandomTopic(); | |
return new TopicDto() | |
.setId(randomTopic.getId()) | |
.setCreated(randomTopic.getCreated()) | |
.setUpdated(randomTopic.getUpdated()) | |
.setName(randomTopic.getName()); | |
})); | |
return Flux.zip(interval, stockTransactionFlux).map(Tuple2::getT2); | |
} | |
@DeleteMapping("{id}") | |
public void delete(@PathVariable final Long id) { | |
log.info("size before: {}", favorites.size()); | |
favorites.removeIf(topic -> topic.getId().equals(id)); | |
log.info("size after: {}. topic id {} removed", favorites.size(), id); | |
} | |
@PostMapping | |
public List<Topic> add(@RequestBody final TopicRequest request) { | |
request.setCreated(LocalDateTime.now()); | |
request.setUpdated(LocalDateTime.now()); | |
log.info("size before: {}", favorites.size()); | |
favorites.add(topicConverter.convertToEntity(request)); | |
log.info("size after: {}. topic id {} added", favorites.size(), request.getId()); | |
return favorites; | |
} | |
private Topic getRandomTopic() { | |
return favorites.get(new Random().nextInt(favorites.size())); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- location: src/main/resources/static/index.html --> | |
<!-- url: http://localhost:8080/index.html --> | |
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" | |
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Document</title> | |
</head> | |
<body> | |
<h1>Socket</h1> | |
<script> | |
var eventSource = new EventSource("http://localhost:8080/v1/api/topic/futures", { | |
withCredentials: true | |
}); | |
// where withCredentials: true // CORS | |
eventSource.onmessage = function(e) { | |
console.log("received: " + e.data); | |
}; | |
// or custom listener | |
// eventSource.addEventListener('join', function(e) { | |
// console.log( 'received ' + e.data ); | |
// }); | |
// if we use WebSocket: | |
// var socket = new WebSocket("ws://localhost:8080/v1/api/topic/futures"); | |
// socket.addEventListener('message', function(event) { | |
// window.alert('message from server: ' + event.data); | |
// }) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment