GRPCClient.swift 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * Copyright 2019, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import NIOConcurrencyHelpers
  17. import NIOCore
  18. import NIOHTTP2
  19. import SwiftProtobuf
  20. /// A gRPC client.
  21. public protocol GRPCClient: GRPCPreconcurrencySendable {
  22. /// The gRPC channel over which RPCs are sent and received. Note that this is distinct
  23. /// from `NIO.Channel`.
  24. var channel: GRPCChannel { get }
  25. /// The call options to use should the user not provide per-call options.
  26. var defaultCallOptions: CallOptions { get set }
  27. }
  28. // MARK: Convenience methods
  29. extension GRPCClient {
  30. public func makeUnaryCall<Request: SwiftProtobuf.Message, Response: SwiftProtobuf.Message>(
  31. path: String,
  32. request: Request,
  33. callOptions: CallOptions? = nil,
  34. interceptors: [ClientInterceptor<Request, Response>] = [],
  35. responseType: Response.Type = Response.self
  36. ) -> UnaryCall<Request, Response> {
  37. return self.channel.makeUnaryCall(
  38. path: path,
  39. request: request,
  40. callOptions: callOptions ?? self.defaultCallOptions,
  41. interceptors: interceptors
  42. )
  43. }
  44. public func makeUnaryCall<Request: GRPCPayload, Response: GRPCPayload>(
  45. path: String,
  46. request: Request,
  47. callOptions: CallOptions? = nil,
  48. interceptors: [ClientInterceptor<Request, Response>] = [],
  49. responseType: Response.Type = Response.self
  50. ) -> UnaryCall<Request, Response> {
  51. return self.channel.makeUnaryCall(
  52. path: path,
  53. request: request,
  54. callOptions: callOptions ?? self.defaultCallOptions,
  55. interceptors: interceptors
  56. )
  57. }
  58. public func makeServerStreamingCall<
  59. Request: SwiftProtobuf.Message,
  60. Response: SwiftProtobuf.Message
  61. >(
  62. path: String,
  63. request: Request,
  64. callOptions: CallOptions? = nil,
  65. interceptors: [ClientInterceptor<Request, Response>] = [],
  66. responseType: Response.Type = Response.self,
  67. handler: @escaping (Response) -> Void
  68. ) -> ServerStreamingCall<Request, Response> {
  69. return self.channel.makeServerStreamingCall(
  70. path: path,
  71. request: request,
  72. callOptions: callOptions ?? self.defaultCallOptions,
  73. interceptors: interceptors,
  74. handler: handler
  75. )
  76. }
  77. public func makeServerStreamingCall<Request: GRPCPayload, Response: GRPCPayload>(
  78. path: String,
  79. request: Request,
  80. callOptions: CallOptions? = nil,
  81. interceptors: [ClientInterceptor<Request, Response>] = [],
  82. responseType: Response.Type = Response.self,
  83. handler: @escaping (Response) -> Void
  84. ) -> ServerStreamingCall<Request, Response> {
  85. return self.channel.makeServerStreamingCall(
  86. path: path,
  87. request: request,
  88. callOptions: callOptions ?? self.defaultCallOptions,
  89. interceptors: interceptors,
  90. handler: handler
  91. )
  92. }
  93. public func makeClientStreamingCall<
  94. Request: SwiftProtobuf.Message,
  95. Response: SwiftProtobuf.Message
  96. >(
  97. path: String,
  98. callOptions: CallOptions? = nil,
  99. interceptors: [ClientInterceptor<Request, Response>] = [],
  100. requestType: Request.Type = Request.self,
  101. responseType: Response.Type = Response.self
  102. ) -> ClientStreamingCall<Request, Response> {
  103. return self.channel.makeClientStreamingCall(
  104. path: path,
  105. callOptions: callOptions ?? self.defaultCallOptions,
  106. interceptors: interceptors
  107. )
  108. }
  109. public func makeClientStreamingCall<Request: GRPCPayload, Response: GRPCPayload>(
  110. path: String,
  111. callOptions: CallOptions? = nil,
  112. interceptors: [ClientInterceptor<Request, Response>] = [],
  113. requestType: Request.Type = Request.self,
  114. responseType: Response.Type = Response.self
  115. ) -> ClientStreamingCall<Request, Response> {
  116. return self.channel.makeClientStreamingCall(
  117. path: path,
  118. callOptions: callOptions ?? self.defaultCallOptions,
  119. interceptors: interceptors
  120. )
  121. }
  122. public func makeBidirectionalStreamingCall<
  123. Request: SwiftProtobuf.Message,
  124. Response: SwiftProtobuf.Message
  125. >(
  126. path: String,
  127. callOptions: CallOptions? = nil,
  128. interceptors: [ClientInterceptor<Request, Response>] = [],
  129. requestType: Request.Type = Request.self,
  130. responseType: Response.Type = Response.self,
  131. handler: @escaping (Response) -> Void
  132. ) -> BidirectionalStreamingCall<Request, Response> {
  133. return self.channel.makeBidirectionalStreamingCall(
  134. path: path,
  135. callOptions: callOptions ?? self.defaultCallOptions,
  136. interceptors: interceptors,
  137. handler: handler
  138. )
  139. }
  140. public func makeBidirectionalStreamingCall<Request: GRPCPayload, Response: GRPCPayload>(
  141. path: String,
  142. callOptions: CallOptions? = nil,
  143. interceptors: [ClientInterceptor<Request, Response>] = [],
  144. requestType: Request.Type = Request.self,
  145. responseType: Response.Type = Response.self,
  146. handler: @escaping (Response) -> Void
  147. ) -> BidirectionalStreamingCall<Request, Response> {
  148. return self.channel.makeBidirectionalStreamingCall(
  149. path: path,
  150. callOptions: callOptions ?? self.defaultCallOptions,
  151. interceptors: interceptors,
  152. handler: handler
  153. )
  154. }
  155. }
  156. /// A client which has no generated stubs and may be used to create gRPC calls manually.
  157. /// See ``GRPCClient`` for details.
  158. ///
  159. /// Example:
  160. ///
  161. /// ```
  162. /// let client = AnyServiceClient(channel: channel)
  163. /// let rpc: UnaryCall<Request, Response> = client.makeUnaryCall(
  164. /// path: "/serviceName/methodName",
  165. /// request: .with { ... },
  166. /// }
  167. /// ```
  168. @available(*, deprecated, renamed: "GRPCAnyServiceClient")
  169. public final class AnyServiceClient: GRPCClient {
  170. private let lock = Lock()
  171. private var _defaultCallOptions: CallOptions
  172. /// The gRPC channel over which RPCs are sent and received.
  173. public let channel: GRPCChannel
  174. /// The default options passed to each RPC unless passed for each RPC.
  175. public var defaultCallOptions: CallOptions {
  176. get { return self.lock.withLock { self._defaultCallOptions } }
  177. set { self.lock.withLockVoid { self._defaultCallOptions = newValue } }
  178. }
  179. /// Creates a client which may be used to call any service.
  180. ///
  181. /// - Parameters:
  182. /// - connection: ``ClientConnection`` to the service host.
  183. /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
  184. public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
  185. self.channel = channel
  186. self._defaultCallOptions = defaultCallOptions
  187. }
  188. }
  189. // Unchecked because mutable state is protected by a lock.
  190. @available(*, deprecated, renamed: "GRPCAnyServiceClient")
  191. extension AnyServiceClient: @unchecked Sendable {}
  192. /// A client which has no generated stubs and may be used to create gRPC calls manually.
  193. /// See ``GRPCClient`` for details.
  194. ///
  195. /// Example:
  196. ///
  197. /// ```
  198. /// let client = GRPCAnyServiceClient(channel: channel)
  199. /// let rpc: UnaryCall<Request, Response> = client.makeUnaryCall(
  200. /// path: "/serviceName/methodName",
  201. /// request: .with { ... },
  202. /// }
  203. /// ```
  204. public struct GRPCAnyServiceClient: GRPCClient {
  205. public let channel: GRPCChannel
  206. /// The default options passed to each RPC unless passed for each RPC.
  207. public var defaultCallOptions: CallOptions
  208. /// Creates a client which may be used to call any service.
  209. ///
  210. /// - Parameters:
  211. /// - connection: ``ClientConnection`` to the service host.
  212. /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
  213. public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
  214. self.channel = channel
  215. self.defaultCallOptions = defaultCallOptions
  216. }
  217. }