|
1 | 1 | <?xml version="1.0" encoding="UTF-8"?>
|
2 | 2 | <!--
|
3 |
| - - Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. |
| 3 | + - Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. |
4 | 4 | -->
|
5 | 5 |
|
6 | 6 | <!DOCTYPE topic
|
|
25 | 25 |
|
26 | 26 | @Rpc
|
27 | 27 | interface MyService : RemoteService {
|
28 |
| - suspend fun sendStream(stream: Flow<Int>): Flow<String> |
| 28 | + fun sendStream(stream: Flow<Int>): Flow<String> |
29 | 29 |
|
30 | 30 | suspend fun streamRequest(request: StreamRequest)
|
31 | 31 | }
|
32 | 32 | </code-block>
|
33 | 33 |
|
34 | 34 | <p>
|
35 | 35 | Another requirement is that server-side steaming (flows that are returned from a function),
|
36 |
| - must be the top-level type: |
| 36 | + must be the top-level type and the function must be non-suspending: |
37 | 37 | </p>
|
38 | 38 |
|
39 | 39 | <code-block lang="kotlin">
|
|
45 | 45 |
|
46 | 46 | @Rpc
|
47 | 47 | interface MyService : RemoteService {
|
48 |
| - suspend fun serverStream(): Flow<String> // ok |
| 48 | + fun serverStream(): Flow<String> // ok |
| 49 | + suspend fun serverStream(): Flow<String> // not ok |
49 | 50 | suspend fun serverStream(): StreamResult // not ok
|
50 | 51 | }
|
51 | 52 | </code-block>
|
|
55 | 56 | <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serializers.md#contextual-serialization">Contextual</a>
|
56 | 57 | annotation.
|
57 | 58 | </note>
|
58 |
| - |
59 |
| - <p> |
60 |
| - To use flows in your code, use the <code>streamScoped</code> function |
61 |
| - that will provide your flows with their lifetime: |
62 |
| - </p> |
63 |
| - |
64 |
| - <code-block lang="kotlin"> |
65 |
| - @Rpc |
66 |
| - interface MyService : RemoteService { |
67 |
| - suspend fun sendFlow(flow: Flow<Int>) |
68 |
| - } |
69 |
| - |
70 |
| - val myService = rpcClient.withService<MyService>() |
71 |
| - |
72 |
| - streamScoped { |
73 |
| - val flow = flow { |
74 |
| - repeat(10) { i -> |
75 |
| - emit(i) |
76 |
| - } |
77 |
| - } |
78 |
| - |
79 |
| - myService.sendFlow(flow) |
80 |
| - } |
81 |
| - </code-block> |
82 |
| - <p> |
83 |
| - In that case all your flows, including incoming and outgoing, |
84 |
| - will work until the <code>streamScoped</code> function completes. |
85 |
| - After that, all streams that are still live will be closed. |
86 |
| - </p> |
87 |
| - <p> |
88 |
| - You can have multiple RPC calls and flows inside the <code>streamScoped</code> function, including those from |
89 |
| - different services. |
90 |
| - </p> |
91 |
| - <p> |
92 |
| - On the server side, you can use the <code>invokeOnStreamScopeCompletion</code> handler inside your methods |
93 |
| - to execute code after <code>streamScoped</code> on the client side has closed. |
94 |
| - It might be useful to clean resources, for example. |
95 |
| - </p> |
96 |
| - <warning> |
97 |
| - Note that this API is experimental and may be removed in future releases. |
98 |
| - </warning> |
99 |
| - <p> |
100 |
| - Another way of managing streams is to do it manually. |
101 |
| - For this, you can use the <code>StreamScope</code> constructor function together with |
102 |
| - <code>withStreamScope</code>: |
103 |
| - </p> |
104 |
| - <code-block lang="kotlin"> |
105 |
| - val streamScope = StreamScope(myJob) |
106 |
| - withStreamScope(streamScope) { |
107 |
| - // use streams here |
108 |
| - } |
109 |
| - </code-block> |
110 | 59 | </chapter>
|
111 | 60 | </topic>
|
0 commit comments