Skip to content

Commit

Permalink
Merge pull request #5533 from MohamedSabthar/master
Browse files Browse the repository at this point in the history
Add Server-Sent Events BBE
  • Loading branch information
MohamedSabthar committed Aug 14, 2024
2 parents 5e30d14 + 2ed9e31 commit 34e3a9b
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 4 deletions.
13 changes: 13 additions & 0 deletions examples/http-sse-client/http_sse_client.bal
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ballerina/http;
import ballerina/io;

public function main() returns error? {
http:Client clientEp = check new ("localhost:9090");
// Make a GET request to the "/stocks" endpoint and receive a stream of `http:SseEvent`.
stream<http:SseEvent, error?> eventStream = check clientEp->/stocks;
// Iterate over the stream and handle each event.
check from http:SseEvent event in eventStream
do {
io:println("Stock price: ", event.data);
};
}
7 changes: 7 additions & 0 deletions examples/http-sse-client/http_sse_client.client.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$ bal run http_sse_client.bal

Stock price: 249.9963321685791
Stock price: 56.58070945739746
Stock price: 571.2127494812012
Stock price: 217.98820853233337
Stock price: 21.891758739948273
16 changes: 16 additions & 0 deletions examples/http-sse-client/http_sse_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# HTTP client - Server-sent events

The HTTP client supports receiving real-time data from services using server-sent events (SSE). It allows payload-binding of a stream of `http:SseEvent` when consuming SSE from a service. This payload binding fails if the content type header is not present in the response or does not have the value `text/event-stream`.

::: code http_sse_client.bal :::

## Prerequisites
- Run the HTTP service given in the [Server-sent events](/learn/by-example/http-sse-service/) example.

Run the client program by executing the following command.

::: out http_sse_client.client.out :::

## Related links
- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)
- [Client action return types - Specification](/spec/http/#243-client-action-return-types)
2 changes: 2 additions & 0 deletions examples/http-sse-client/http_sse_client.metatags
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
description: This example demonstrates how server-sent events (SSE) can be consumed using an HTTP client.
keywords: ballerina, ballerina by example, bbe, http, SSE, client
33 changes: 33 additions & 0 deletions examples/http-sse-service/http_sse_service.bal
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import ballerina/http;
import ballerina/lang.runtime;
import ballerina/random;

service /stocks on new http:Listener(9090) {
// This resource method returns a stream of `http:SseEvent` (with stock prices)
// to push real-time data to clients using server-sent events (SSE).
resource function get .() returns stream<http:SseEvent, error?> {
// Create a new value of type `StockPriceEventGenerator` to generate stock price events.
StockPriceEventGenerator generator = new;
// Return a new stream that uses the generator to produce events.
return new (generator);
}
}

// Define a stream implementor that can be used to create a stream
// of `http:SseEvent`, representing stock price events.
class StockPriceEventGenerator {
int eventCounter = 0;

public isolated function next() returns record {|http:SseEvent value;|}|error? {
// If the eventCounter reaches 5, stop generating events by returning nil.
if self.eventCounter == 5 {
return ();
}
self.eventCounter += 1;
runtime:sleep(1);
// Generate a random stock price
float stockPrice = (check random:createIntInRange(1, 1000)) * random:createDecimal();
http:SseEvent event = {data: stockPrice.toString()};
return {value: event};
}
}
27 changes: 27 additions & 0 deletions examples/http-sse-service/http_sse_service.client.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
$ curl -v localhost:9090/stocks
* Trying [::1]:9090...
* Connected to localhost (::1) port 9090
> GET /stocks/stockA HTTP/1.1
> Host: localhost:9090
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: text/event-stream
< cache-control: no-cache,public
< transfer-encoding: chunked
< connection: keep-alive
< server: ballerina
< date: Fri, 2 Aug 2024 12:02:04 +0530
<
data: 76.6014928817749

data: 789.1765828132629

data: 241.89215344190598

data: 494.8120536804199

data: 234.36854779720306

* Connection #0 to host localhost left intact
17 changes: 17 additions & 0 deletions examples/http-sse-service/http_sse_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# HTTP service - Server-sent events

Ballerina HTTP services support pushing real-time data to clients using server-sent events (SSE). A stream of type `http:SseEvent` can be returned from service resource methods. This feature automatically handles sending SSE and sets the content type to `text/event-stream` and the transfer encoding to chunked.

::: code http_sse_service.bal :::

Run the service program by executing the following command.

::: out http_sse_service.server.out :::

Invoke the service by executing the following cURL command in a new terminal.

::: out http_sse_service.client.out :::

## Related links
- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)
- [Resource return types - Specification](/spec/http/#235-return-types)
2 changes: 2 additions & 0 deletions examples/http-sse-service/http_sse_service.metatags
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
description: This example demonstrates how server-sent events (SSE) can be produced using an HTTP service.
keywords: ballerina, ballerina by example, bbe, http, SSE, service
1 change: 1 addition & 0 deletions examples/http-sse-service/http_sse_service.server.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ bal run http_sse_service.bal
16 changes: 16 additions & 0 deletions examples/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -2256,6 +2256,14 @@
"verifyOutput": false,
"disablePlayground": false,
"isLearnByExample": false
},
{
"name": "Server-sent events",
"url": "http-sse-service",
"verifyBuild": true,
"verifyOutput": false,
"disablePlayground": false,
"isLearnByExample": false
}
]
},
Expand Down Expand Up @@ -2327,6 +2335,14 @@
"verifyOutput": false,
"disablePlayground": false,
"isLearnByExample": false
},
{
"name": "Server-sent events",
"url": "http-sse-client",
"verifyBuild": true,
"verifyOutput": false,
"disablePlayground": false,
"isLearnByExample": false
}
]
},
Expand Down
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ stdlibLdapVersion=1.0.0
# Stdlib Level 02
stdlibAvroVersion=1.0.0
stdlibConstraintVersion=1.5.0
stdlibCryptoVersion=2.7.0
stdlibCryptoVersion=2.7.2
stdlibDataXmldataVersion=0.1.4
stdlibLogVersion=2.9.0
stdlibOsVersion=1.8.0
Expand All @@ -40,7 +40,7 @@ observeInternalVersion=1.2.2
stdlibCacheVersion=3.8.0
stdlibFileVersion=1.9.0
stdlibFtpVersion=2.10.1
stdlibMimeVersion=2.9.0
stdlibMimeVersion=2.10.0-20240724-124600-f193322
stdlibTcpVersion=1.10.0
stdlibUdpVersion=1.10.0
stdlibUuidVersion=1.8.0
Expand All @@ -51,14 +51,14 @@ stdlibDataJsondataVersion=0.1.0
stdlibDataYamlVersion=0.1.0-20240805-142200-476565f
stdlibEdiVersion=1.2.0
stdlibEmailVersion=2.9.0
stdlibJwtVersion=2.11.0
stdlibJwtVersion=2.12.1
stdlibMqttVersion=1.1.1
stdlibOAuth2Version=2.11.0
stdlibTomlVersion=0.5.1
stdlibYamlVersion=0.5.3

# Stdlib Level 05
stdlibHttpVersion=2.11.1
stdlibHttpVersion=2.12.0-20240801-081400-0b676d6

# Stdlib Level 06
stdlibGrpcVersion=1.11.1
Expand Down

0 comments on commit 34e3a9b

Please sign in to comment.