SSE от Java до веб-браузера
Я подумал, что выпуск HTTP SSE из Java и обработка этих соединений не должны быть такими сложными, но я не могу понять, как это сделать.
У меня есть один сервер (Java SE 11) и несколько клиентов (веб-браузеры с JavaScript), которые начинают прослушивать сообщения с сервера. (Я тестирую на локальном хосте)
Клиентская сторона очень проста:
var evtSource = new EventSource("localhost/javaapp");
evtSource.onmessage = function(e) {
console.log("message: " + e.data);
}
evtSource.onerror = function(e) {
console.log("sse failed");
}
Но на стороне сервера я понятия не имею. После некоторого расследования я обнаружил, что мне следует использовать javax.ws.rs.sse
API, но все, что у него есть, это интерфейсы и примеры кода, которые вы обнаружите, используют множество @Annotations, вещей, которых я бы хотел избежать.
Мне вообще нужен этот API? Или я могу просто создать простое HTTP-соединение с соответствующими заголовками? Но тогда как реализовать все возможности SSE? Автоматика поддерживает жизнь и так далее...
Цель состоит в том, чтобы обращаться со всеми клиентами отдельно. Они подписываются на сервер, и в случае, если какое-либо событие происходит для одного, сервер отправляет сообщение этому. Так что речь не идет о вещании одного и того же всем.
0 ответов
Используя Spring Web, вы можете просто создать объект SseEmitter, а затем отправить ему данные.
и вы можете получать данные от своего клиента как есть.
@Controller
@RequestMapping(path = "api/person")
public class PersonController {
@Autowired
private PersonRepository personRepository;
private Optional<SseEmitter> sseEmitter = Optional.empty();
@PostMapping(path = "/add")
public @ResponseBody
String addPerson(@RequestBody Person person) {
personRepository.save(person);
sseEmitter.ifPresent(sseEmitter1 -> {
try {
sseEmitter1.send(person);
} catch (IOException e) {
e.printStackTrace();
}
}
);
return "Saved";
}
@GetMapping(path = "/onPersonAdded")
public SseEmitter onPersonAdded() {
sseEmitter = Optional.of(sseEmitter.orElse(new SseEmitter(-1L)));
return sseEmitter.get();
}
}