ios - 如何在 iOS 应用中使用 swift 进行 gRPC 调用
问题描述
我正在尝试使用https://github.com/grpc/grpc-swift访问一些谷歌云 RPC API
我所做的与Natural Language Example非常相似。
我能够从 master 分支上获得一个与 0.10.0 版本一起使用的版本,但自述文件说这个分支已被弃用,应该使用“nio”分支。
不幸的是,示例代码与项目不同步,无法编译。我尽力修复代码,但我无法让它工作。
class NaturalLanguageRPCTests {
let authToken : String
var service : Google_Cloud_Language_V1_LanguageServiceServiceClient?
var clientConnection : ClientConnection?
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
init(authToken: String) {
self.authToken = authToken
}
func createService() {
let host = "language.googleapis.com"
let port = 443
let tls = ClientConnection.Configuration.TLS(configuration: TLSConfiguration.forClient(applicationProtocols: ["h2"]))
let configuration = ClientConnection.Configuration(target: .hostAndPort(host, port),
eventLoopGroup: self.eventLoopGroup,
errorDelegate: self,
connectivityStateDelegate: self,
tls: tls)
//connectionBackoff: ConnectionBackoff?)
self.clientConnection = ClientConnection(configuration: configuration)
}
func makeRPCCall() {
guard let connection = self.clientConnection, connection.connectivity.state == .ready else {
fatalError()
}
if self.service == nil {
self.service = Google_Cloud_Language_V1_LanguageServiceServiceClient(connection: connection)
}
guard let service = self.service else {
print("SERVICE HASN'T BEEN CREATED YET")
return
}
// Use CallOptions to send the auth token (necessary) and set a custom timeout (optional).
let http_headers = HTTPHeaders([("authorization", "Bearer " + self.authToken)])
let headers = HPACKHeaders(httpHeaders: http_headers)
let timeout = try! GRPCTimeout.seconds(30)
let callOptions = CallOptions(customMetadata: headers, timeout: timeout)
print("CALL OPTIONS\n\(callOptions)\n")
// Construct the API request.
var document = Google_Cloud_Language_V1_Document()
document.type = .plainText
document.content = "The Caterpillar and Alice looked at each other for some time in silence: at last the Caterpillar took the hookah out of its mouth, and addressed her in a languid, sleepy voice. `Who are you?' said the Caterpillar."
var features = Google_Cloud_Language_V1_AnnotateTextRequest.Features()
features.extractSyntax = true
features.extractEntities = true
features.extractDocumentSentiment = true
features.extractEntitySentiment = true
features.classifyText = true
var request = Google_Cloud_Language_V1_AnnotateTextRequest()
request.document = document
request.features = features
print("REQUEST MESSAGE\n\(request)")
// Create/start the API call.
let call = service.annotateText(request, callOptions: callOptions)
call.response.whenSuccess { response in
print("CALL SUCCEEDED WITH RESPONSE\n\(response)")
}
call.response.whenFailure { error in
print("CALL FAILED WITH ERROR\n\(error)")
}
do {
// wait() on the status to stop the program from exiting.
let status = try call.status.wait()
print("CALL STATUS\n\(status)")
} catch {
print("EXAMPLE FAILED WITH ERROR\n\(error)")
}
}
}
当我调用
test.createService()
并监视连接的状态时,它会转换为“就绪”,因此我假设正在建立连接。
但是,当我打电话时,test.makeRPCCall()
我得到了错误。从日志:
2019-11-29T20:10:23-0800 info: path=/google.cloud.language.v1.LanguageService/AnnotateText
request_id=0EAC0A92-2842-4D5A-BC94-B0BD4D6171EF starting rpc
CALL STATUS
unimplemented (12): invalid HTTP status: Not Found
2019-11-29T20:10:48-0800 info: duration_ms=46 request_id=0EAC0A92-2842-4D5A-BC94-B0BD4D6171EF status_code=12 rpc call finished
CALL FAILED WITH ERROR
unimplemented (12): invalid HTTP status: Not Found
我确定这很简单,我做错了,但我无法让它为我的生活工作。如果有人对此有所了解,我将不胜感激。谢谢。
解决方案
回答我自己的问题。
- grpc-swift 中存在一个已修复的错误。那里的开发人员的响应时间真棒!!!因此,您必须从 nio 分支获取最新版本,因为还没有带有修复的版本。
这是工作代码
class NaturalLanguageRPCTests { let authToken : String var service : Google_Cloud_Language_V1_LanguageServiceServiceClient? var clientConnection : ClientConnection? let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) init(authToken: String) { self.authToken = authToken } func createService() { let host = "language.googleapis.com" let port = 443 let configuration = ClientConnection.Configuration( target: .hostAndPort(host, port), eventLoopGroup: eventLoopGroup, tls: .init() ) self.clientConnection = ClientConnection(configuration: configuration) } func makeRPCCall() { guard let connection = self.clientConnection, connection.connectivity.state == .ready else { fatalError() } if self.service == nil { self.service = Google_Cloud_Language_V1_LanguageServiceServiceClient(connection: connection) } guard let service = self.service else { print("SERVICE HASN'T BEEN CREATED YET") return } // Use CallOptions to send the auth token (necessary) and set a custom timeout (optional). let headers: HPACKHeaders = ["authorization": "Bearer \(authToken)"] let callOptions = CallOptions(customMetadata: headers, timeout: .seconds(rounding: 30)) print("CALL OPTIONS\n\(callOptions)\n") // Construct the API request. var document = Google_Cloud_Language_V1_Document() document.type = .plainText document.content = "The Caterpillar and Alice looked at each other for some time in silence: at last the Caterpillar took the hookah out of its mouth, and addressed her in a languid, sleepy voice. `Who are you?' said the Caterpillar." var features = Google_Cloud_Language_V1_AnnotateTextRequest.Features() features.extractSyntax = true features.extractEntities = true features.extractDocumentSentiment = true features.extractEntitySentiment = true features.classifyText = true var request = Google_Cloud_Language_V1_AnnotateTextRequest() request.document = document request.features = features print("REQUEST MESSAGE\n\(request)") // Create/start the API call. let call = service.annotateText(request, callOptions: callOptions) call.response.whenSuccess { response in print("CALL SUCCEEDED WITH RESPONSE\n\(response)") } call.response.whenFailure { error in print("CALL FAILED WITH ERROR\n\(error)") } do { // wait() on the status to stop the program from exiting. let status = try call.status.wait() print("CALL STATUS\n\(status)") } catch { print("EXAMPLE FAILED WITH ERROR\n\(error)") } }}
推荐阅读
- flutter - onPlacePicked 的 SetState 到 Text Flutter
- apache - 从 .htaccess 获取查询字符串参数在 PHP 中重写 URL
- java - 我不能在 IntelliJ 中使用多个类
- database - 错误:“ORA-01805:日期/时间操作中可能出现错误”,如何升级客户端时区文件
- python - Python 无法在标头“会话令牌”中放置变量
- python - Android客户端不会从python服务器接收
- unity3d - Unity - 在预制件中查找特定的游戏对象(克隆)
- php - 我的关系没有反映在我的数据库中。symfony 主义
- algorithm - 高于 T(n) 的大 Oh 符号
- python - python selenium webscraping(单击显示数据的按钮然后提取它)