問題
宜州ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
在手機(jī)應(yīng)用的開發(fā)中,通常會(huì)將復(fù)雜的業(yè)務(wù)邏輯層實(shí)現(xiàn)放在服務(wù)端,客戶端僅負(fù)責(zé)表現(xiàn)層。但是對(duì)于某些手機(jī)應(yīng)用而言,業(yè)務(wù)邏輯的實(shí)現(xiàn)位于服務(wù)端反而是不安全的或是不合理的,而是需要將其邏輯直接在手機(jī)端實(shí)現(xiàn)。
目的
面對(duì)不同系統(tǒng)的手機(jī)客戶端,單獨(dú)重復(fù)實(shí)現(xiàn)相同的業(yè)務(wù)邏輯,并非最佳實(shí)踐。如何通過第三方語言 Go 語言將業(yè)務(wù)邏輯封裝成庫的形式,并以靜態(tài)打包的方式提供給不同系統(tǒng)的手機(jī)客戶端使用,是本次調(diào)研的目的。
理想目標(biāo)圖:
cdn.xitu.io/2019/7/4/16bbd44a4c33a8ce?w=930&h=427&f=png&s=28182">
具體調(diào)研內(nèi)容包括:
其中關(guān)于 gRPC 在 iOS 與 Android 的實(shí)現(xiàn),本身官方就已經(jīng)提供了樣例。本次調(diào)研會(huì)用到相關(guān)內(nèi)容,所以將其作為調(diào)研的一部分記錄下來,方便后來者閱讀。調(diào)研中所有涉及的項(xiàng)目代碼均存放于: liujianping/grpc-apps 倉庫中, 需要的朋友可以直接下載測(cè)試。
原文發(fā)布在我的個(gè)人站點(diǎn): GitDiG.com. 原文鏈接:iOS 應(yīng)用實(shí)現(xiàn) gRPC 調(diào)用 .
作為一名非專職 iOS 的程序員,經(jīng)常需要調(diào)研陌生的技術(shù)或者語言。首先是要克服對(duì)于未知的畏懼心理。其實(shí)很多東西沒那么難,只是需要開始而已。 為了完成目標(biāo)調(diào)研,開始第一部分的調(diào)研工作。以文字形式記錄下來,方便后來者。
沒什么好說的,直接 AppStore 下載安裝。有點(diǎn)慢,一邊下載一邊準(zhǔn)備其它環(huán)境。
類似與其它語言的第三方庫管理工具。也沒什么好說的,登錄官網(wǎng),按說明安裝。
$: sudo gem install cocoapods
因?yàn)?gRPC 的廣泛使用, ProtoBuf 協(xié)議被廣泛用于字節(jié)編碼與解碼的協(xié)議, 其具體指南參考[官網(wǎng)]()。話不多說,安裝:
$: curl -LOk https://github.com/protocolbuffers/protobuf/releases/download/v3.5.1/protoc-3.9.0-rc-1-osx-x86_64.zip
$: unzip protoc-3.9.0-rc-1-osx-x86_64.zip -d proto_buffer && cd proto_buffer
$: sudo cp bin/protoc /usr/local/bin
$: sudo cp -R include/google/protobuf/ /usr/local/include/google/protobuf
$: protoc --version
protoc 主要是通過解析 .proto
格式的文件, 再根據(jù)具體插件生成相應(yīng)語言代碼。
考慮到需要同時(shí)實(shí)現(xiàn)客戶端與服務(wù)端的代碼,所以必須安裝以下三個(gè)插件:
swift 插件安裝:
$: git clone https://github.com/grpc/grpc-swift.git
$: cd grpc-swift
$: git checkout tags/0.5.1
$: make
$: sudo cp protoc-gen-swift protoc-gen-swiftgrpc /usr/local/bin
go 插件安裝:
前提是需要安裝 Go 語言的開發(fā)環(huán)境, 可參考官網(wǎng)。protoc-gen-go
安裝詳細(xì)指南.
$: go get -u github.com/golang/protobuf/protoc-gen-go
既然是最簡(jiǎn)單的調(diào)研,就用最簡(jiǎn)單的 Hello 服務(wù)。創(chuàng)建項(xiàng)目路徑并定義:
$: mkdir grpc-apps
$: cd grpc-apps
$: mkdir proto
$: cat <<EOF > proto/hello.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.gitdig.helloworld";
option java_outer_classname = "HelloWorldProto";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
EOF
在項(xiàng)目目錄中創(chuàng)建服務(wù)端目錄與proto生成目錄,同時(shí)編寫一個(gè)簡(jiǎn)單的服務(wù)端:
$: cd grpc-apps
$: mkdir go go/client go/server go/hello
# 生成 Go 代碼到 go/hello 文件夾
$: protoc -I proto proto/hello.proto --go_out=plugins=grpc:./go/hello/
分別編輯 Go 版本 client 與 server 實(shí)現(xiàn)。確認(rèn)服務(wù)正常運(yùn)行。
編輯 server/server.go
文件:
package main
import (
pb "github.com/liujianping/grpc-apps/go/helloworld"
)
import (
"context"
"fmt"
"log"
"net"
"google.golang.org/grpc"
)
type HelloServer struct{}
// SayHello says 'hi' to the user.
func (hs *HelloServer) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
// create response
res := &pb.HelloReply{
Message: fmt.Sprintf("hello %s from go", req.Name),
}
return res, nil
}
func main() {
var err error
// create socket listener
l, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("error: %v\n", err)
}
// create server
helloServer := &HelloServer{}
// register server with grpc
s := grpc.NewServer()
pb.RegisterGreeterServer(s, helloServer)
log.Println("server serving at: :50051")
// run
s.Serve(l)
}
運(yùn)行服務(wù)端程序:
$: cd grpc-apps/go
$: go run server/server.go
2019/07/03 20:31:06 server serving at: :50051
編輯 client/client.go
文件:
package main
import (
pb "github.com/liujianping/grpc-apps/go/helloworld"
)
import (
"context"
"fmt"
"log"
"google.golang.org/grpc"
)
func main() {
var err error
// connect to server
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("error: %v\n", err)
}
defer conn.Close()
// create client
client := pb.NewGreeterClient(conn)
// create request
req := &pb.HelloRequest{Name: "JayL"}
// call method
res, err := client.SayHello(context.Background(), req)
if err != nil {
log.Fatalf("error: %v\n", err)
}
// handle response
fmt.Printf("Received: \"%s\"\n", res.Message)
}
執(zhí)行客戶端程序:
$: cd grpc-apps/go
$: go run client/client.go
Received: "hello JayL from go"
Go 客戶端/服務(wù)端通信成功。
創(chuàng)建一個(gè)名為 iosDemo 的單視圖項(xiàng)目,選擇 swift 語言, 存儲(chǔ)路徑放在 grpc-apps
下。完成創(chuàng)建后,正常運(yùn)行,退出程序。
在命令行執(zhí)行初始化:
$: cd grpc-apps/iosDemo
# 初始化
$: pod init
$: vim Podfile
編輯 Podfile 如下:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'iosDemo' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for iosDemo
pod 'SwiftGRPC'
end
完成編輯后保存,執(zhí)行安裝命令:
$: pod install
安裝完成后,項(xiàng)目目錄發(fā)生以下變更:
$: git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: iosDemo.xcodeproj/project.pbxproj
Untracked files:
(use "git add <file>..." to include in what will be committed)
Podfile
Podfile.lock
Pods/
iosDemo.xcworkspace/
no changes added to commit (use "git add" and/or "git commit -a")
通過命令行 open iosDemo.xcworkspace
打開項(xiàng)目,對(duì)項(xiàng)目中的info.list的以下設(shè)置進(jìn)行修改:
通過設(shè)置,開啟非安全的HTTP訪問方式。
類似 Go 代碼生成,現(xiàn)在生成 swift 代碼:
$: cd grpc-apps
# 創(chuàng)建生成文件存放目錄
$: mkdir swift
# 生成 swift 文件
$: protoc -I proto proto/hello.proto \
--swift_out=./swift/ \
--swiftgrpc_out=Client=true,Server=false:./swift/
# 生成文件查看
$: tree swift
swift
├── hello.grpc.swift
└── hello.pb.swift
XCode中添加生成代碼需要通過拖拽的方式,對(duì)于后端開發(fā)而言,確實(shí)有點(diǎn)不可理喻。不過既然必須這樣就按照規(guī)則:
現(xiàn)在在 iOS 的視圖加載函數(shù)增加 gRPC 調(diào)用過程:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let client = Helloworld_GreeterServiceClient(address: ":50051", secure: false)
var req = Helloworld_HelloRequest()
req.name = "JayL"
do {
let resp = try client.sayHello(req)
print("resp: \(resp.message)")
} catch {
print("error: \(error.localizedDescription)")
}
}
}
查看日志輸出resp: hello iOS from go
, iOS 應(yīng)用調(diào)用 gRPC 服務(wù)成功。
文章名稱:記一次技術(shù)調(diào)研(一):iOS應(yīng)用實(shí)現(xiàn)gRPC調(diào)用
URL標(biāo)題:http://www.rwnh.cn/article28/jcjjcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、網(wǎng)站營(yíng)銷、網(wǎng)站設(shè)計(jì)公司、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)