forked from bclozel/webflux-workshop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use the WebClient to stream JSON to the browser
- Loading branch information
Showing
4 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
61 changes: 61 additions & 0 deletions
61
trading-service/src/main/java/io/spring/workshop/tradingservice/Quote.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package io.spring.workshop.tradingservice; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.MathContext; | ||
import java.time.Instant; | ||
|
||
public class Quote { | ||
|
||
private static final MathContext MATH_CONTEXT = new MathContext(2); | ||
|
||
private String ticker; | ||
|
||
private BigDecimal price; | ||
|
||
private Instant instant; | ||
|
||
public Quote() { | ||
} | ||
|
||
public Quote(String ticker, BigDecimal price) { | ||
this.ticker = ticker; | ||
this.price = price; | ||
} | ||
|
||
public Quote(String ticker, Double price) { | ||
this(ticker, new BigDecimal(price, MATH_CONTEXT)); | ||
} | ||
|
||
public String getTicker() { | ||
return ticker; | ||
} | ||
|
||
public void setTicker(String ticker) { | ||
this.ticker = ticker; | ||
} | ||
|
||
public BigDecimal getPrice() { | ||
return price; | ||
} | ||
|
||
public void setPrice(BigDecimal price) { | ||
this.price = price; | ||
} | ||
|
||
public Instant getInstant() { | ||
return instant; | ||
} | ||
|
||
public void setInstant(Instant instant) { | ||
this.instant = instant; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Quote{" + | ||
"ticker='" + ticker + '\'' + | ||
", price=" + price + | ||
", instant=" + instant + | ||
'}'; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
trading-service/src/main/java/io/spring/workshop/tradingservice/QuotesController.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package io.spring.workshop.tradingservice; | ||
|
||
import reactor.core.publisher.Flux; | ||
|
||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.ResponseBody; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
|
||
import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; | ||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM_VALUE; | ||
|
||
@Controller | ||
public class QuotesController { | ||
|
||
@GetMapping("/quotes") | ||
public String quotes() { | ||
return "quotes"; | ||
} | ||
|
||
@GetMapping(path = "/quotes/feed", produces = TEXT_EVENT_STREAM_VALUE) | ||
@ResponseBody | ||
public Flux<Quote> quotesStream() { | ||
return WebClient.create("http://localhost:8081") | ||
.get() | ||
.uri("/quotes") | ||
.accept(APPLICATION_STREAM_JSON) | ||
.retrieve() | ||
.bodyToFlux(Quote.class) | ||
.share() | ||
.log("io.spring.workshop.tradingservice"); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<meta charset="utf-8"/> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"/> | ||
<meta name="description" content="Spring WebFlux Workshop"/> | ||
<meta name="author" content="Violeta Georgieva and Brian Clozel"/> | ||
<title>Spring Trading application</title> | ||
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7/css/bootstrap-theme.min.css"/> | ||
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7/css/bootstrap.min.css"/> | ||
<link rel="stylesheet" href="/webjars/highcharts/5.0.8/css/highcharts.css"/> | ||
</head> | ||
<body> | ||
<nav class="navbar navbar-default"> | ||
<div class="container-fluid"> | ||
<div class="navbar-header"> | ||
<a class="navbar-brand" href="/">Spring Trading application</a> | ||
</div> | ||
<div id="navbar" class="navbar-collapse collapse"> | ||
<ul class="nav navbar-nav"> | ||
<li><a href="/">Home</a></li> | ||
<li class="active"><a href="/quotes">Quotes</a></li> | ||
<li><a href="/websocket">Websocket</a></li> | ||
</ul> | ||
</div> | ||
</div> | ||
</nav> | ||
<div class="container wrapper"> | ||
<div id="chart" style="height: 400px; min-width: 310px"></div> | ||
</div> | ||
<script type="text/javascript" src="/webjars/jquery/1.11.1/jquery.min.js"></script> | ||
<script type="text/javascript" src="/webjars/highcharts/5.0.8/highcharts.js"></script> | ||
<script type="text/javascript" src="/webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script> | ||
<script type="text/javascript"> | ||
|
||
// Setting up the chart | ||
var chart = new Highcharts.chart('chart', { | ||
title: { | ||
text: 'My Stock Portfolio' | ||
}, | ||
yAxis: { | ||
title: { | ||
text: 'Stock Price' | ||
} | ||
}, | ||
legend: { | ||
layout: 'vertical', | ||
align: 'right', | ||
verticalAlign: 'middle' | ||
}, | ||
xAxis: { | ||
type: 'datetime', | ||
}, | ||
series: [{ | ||
name: 'CTXS', | ||
data: [] | ||
}, { | ||
name: 'MSFT', | ||
data: [] | ||
}, { | ||
name: 'ORCL', | ||
data: [] | ||
}, { | ||
name: 'RHT', | ||
data: [] | ||
}, { | ||
name: 'VMW', | ||
data: [] | ||
}, { | ||
name: 'DELL', | ||
data: [] | ||
}] | ||
}); | ||
|
||
// This function adds the given data point to the chart | ||
var appendStockData = function (quote) { | ||
chart.series | ||
.filter(function (serie) { | ||
return serie.name == quote.ticker | ||
}) | ||
.forEach(function (serie) { | ||
var shift = serie.data.length > 40; | ||
serie.addPoint([quote.instant * 1000, quote.price], true, shift); | ||
}); | ||
}; | ||
|
||
// The browser connects to the server and receives quotes using ServerSentEvents | ||
// those quotes are appended to the chart as they're received | ||
var stockEventSource = new EventSource("/quotes/feed"); | ||
stockEventSource.onmessage = function (e) { | ||
appendStockData(JSON.parse(e.data)); | ||
}; | ||
</script> | ||
</body> | ||
</html> |