Build a Mobile App Using Google Compute Engine and gRPC

The gRPC framework makes it possible for a mobile app to directly call methods on a backend service as if it was a local object. You can use gRPC to make your mobile app more bandwidth-efficient and to reduce latency between your app and backend service running on Google Cloud Platform.

Running your mobile backend on Google Compute Engine and using gRPC as the communication protocol between your mobile app and the backend server has several advantages.

  • It is the fastest way to move an existing service, running on an on-premises or virtual machine, to Cloud Platform.
  • Better bandwidth efficiency compared to HTTP/S.
  • It gives you full control over your virtual machine and server configuration.
  • You can use third party libraries.
  • You can configure an autoscaler to scale the number of virtual machines to meet demand.

The downside to running your service on Compute Engine is that you are responsible for maintaining and updating your server manually. For other options for building mobile backend services, see Build mobile apps using Google Cloud Platform.

This tutorial walks you through building a sample mobile app called Stickynotes. This sample app uses gRPC to connect to a backend service running on Compute Engine.

The Stickynotes sample includes code for a frontend mobile app and a backend service. In the mobile app, you can enter a message into a text field. The app sends your message to a backend service using gRPC. The backend service which converts the text message into an image using draw2d, and then returns the image to the mobile app. The mobile app then displays your message as an image with a yellow background.

The client app is an iOS app and the backend service is written in Go.

Objectives

In this tutorial you will learn how to:

  • Create an iOS mobile app that uses gRPC to connect to a backend service.
  • Configure and run a gRPC backend service on Compute Engine.

Costs

This tutorial uses billable components of Cloud Platform, including:

  • Google Compute Engine

Use the Pricing Calculator to generate a costc estimate based on your projected usage. New Cloud Platform users might be eligible for a free trial.

Before you begin

  1. In the GCP Console, go to the Manage resources page.

    Go to the Manage resources page

  2. Select a project, or click Create and create a new GCP project.

    确保您的项目已启用结算功能。

    了解如何启用结算功能

After you've performed these steps, install the following software:

  • Git
  • XCode 7.2 or later
  • Go

    Ensure that the Go installation is in your PATH variable, typically /usr/local/go/bin.

    Install Go with your user account as the owner. If you install it as root, run the following command in the directory where Go is nstalled to change ownership, replacing <username> with your user name.

    sudo chown -R <username> go
    
  • Cocoapods

    sudo gem install cocoapods
    
  • Homebrew

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
  • protoc with the gRPC plugin

    curl -fsSL https://goo.gl/getgrpc | bash -
    

Clone the sample code

git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git

Then navigate to /solutions/stickynoteapi/gRPC to find the sample code for this solution.

Run the server locally

In the /stickynoteapi/gRPC/Go directory, run the following command

sh SETUP

You should see the following output:

0. Ensure that protoc is installed.
/usr/local/bin/protoc
OK
1. Set gopath and search path
2. Get the Go plugin for protoc
3. Run protoc to generate the service API code
4. Get the server and client dependencies
5. Build the server and client
6. Stop any previously-running instances of the server
No matching processes belonging to you were found
7. Start the server
8. Run the client
2016/03/03 15:53:21 OK: message.png
9. Open the image in message.png

The setup also runs a local client to test the server with the phrase “Remember the milk.” and generates an image with that message.

Remember the milk.

To generate images based on your own messages using the command-line client, run the following command.

./client "This is a test..."

The file, /solutions/stickynoteapi/gRPC/Go/go/src/server/server.go, contains the code that runs the gRPC server. The code also defines a structure, StickyNoteServer that contains two elements, one representing the Request, and the other the Response.

type StickyNoteServer struct{}

var stickyNoteServer StickyNoteServer

The main function defines a gRPC server for the root-level directory, which listens for traffic on port 8080. Because the server does not specify an IP address or domain, you can run this code on Compute Engine without any modification.

func main() {
	var err error
	var lis net.Listener
	var grpcServer *grpc.Server
	if !useSSL {
		lis, err = net.Listen("tcp", ":8080")
		if err != nil {
			log.Fatalf("failed to listen: %v", err)
		}
		grpcServer = grpc.NewServer()
	} else {
		certFile := "ssl.crt"
		keyFile := "ssl.key"
		creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
		lis, err = net.Listen("tcp", ":443")
		if err != nil {
			log.Fatalf("failed to listen: %v", err)
		}
		grpcServer = grpc.NewServer(grpc.Creds(creds))
	}
	pb.RegisterStickyNoteServer(grpcServer, &stickyNoteServer)
	grpcServer.Serve(lis)
}

The Get function receives the message in the gRPC request, uses functions defined in sticky.go to build an image based on that message, and then returns the image in a gRPC response.

func (s *StickyNoteServer) Get(ctx context.Context, r *pb.StickyNoteRequest) (*pb.StickyNoteResponse, error) {
	var sticky Sticky
	sticky.Message = r.Message
	sticky.Centered = false

	resp := &pb.StickyNoteResponse{}
	stickyBytes, err := sticky.DrawPNG(512, 512)
	resp.Image = *stickyBytes

	return resp, err
}

Leave the local server running so you can use it to test the client application.

Run the iOS client with the local server

  1. In the /stickynoteapi/gRPC/Objective-C directory, run the following command to install the BoringSSL, Protobuf, and gRPC dependencies. The installation process may take several minutes.

    pod install
    

    You should see the following output:

    Analyzing dependencies
    Fetching podspec for `stickynote` from `stickyapi`
    Downloading dependencies
    Installing BoringSSL (2.0)
    Installing Protobuf (3.0.0-beta-2)
    Installing gRPC (0.12.0)
    Installing stickynote (0.0.1)
    Generating Pods project
    Integrating client project
    
    [!] Please close any current Xcode sessions and use
    `stickynotes.xcworkspace` for this project from now on.
    Sending stats
    Pod installation complete! There is 1 dependency from the Podfile and 4
    total pods installed.
    
  2. Open the workspace built by Cocoapods, stickynotes.xcworkspace, in Xcode.

  3. Select Product > Scheme > stickynotes to pick the correct scheme.

  4. Select Product > Run to build and start the client application. Ignore the warnings in Protobuf and gRPC.

  5. Enter a message in the text field and tap Return.

An image of a yellow sticky note with your message should appear beneath the text field.

This is a test...

The client app sets the location of the backend service in the file StickyNotesViewController.m. For testing purposes, this is initially set to localhost.

static NSString * const kHostAddress = @"localhost";

When you tap Return after entering your message in the text field, the following action fires. The action encodes the message into a query string. Then it passes the query into an open streaming connection.

- (IBAction)textDidChange:(UITextField *) sender {
  if ([_streamSwitch isOn]) {
    StickyNoteRequest *request = [StickyNoteRequest message];
    request.message = sender.text;
    [_writer writeValue:request];
  }
}

The streaming connection is opened by the function openStreamingConnection.

- (void) openStreamingConnection {
  _writer = [[GRXBufferedPipe alloc] init];
  _updateCall = [_client RPCToUpdateWithRequestsWriter:_writer
                                          eventHandler:^(BOOL done, StickyNoteResponse *response, NSError *error) {
                                            [self handleStickynoteResponse:response andError:error];
                                          }];
  [_updateCall start];
}

Run the server on Compute Engine

  1. Go to the Create an instance page in the Google Cloud Platform Console.

    Go to the Create an instance page

    1. Set Name to sticky-grpc.
    2. Select Create.

    Create an instance

  2. Go to the Create a firewall rule page in the GCP Console.

    Go to the Create a firewall rule page

    1. In Name, enter default-allow-grpc.
    2. In Source filter, select Allow from any source (0.0.0.0./0).
    3. In Allowed protocols and ports, enter tcp:8080.
    4. Select Create

    Select SSH

  3. Go to the View your VM instances page in the GCP Console.

    Go to the View your VM instances page

    1. Note the External IP address next to sticky-grpc.
    2. Select SSH

    Select SSH

  4. Install Git on the instance.

    sudo apt-get update
    sudo apt-get install git
    
  5. Clone the Stickynotes server code.

    git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git
    
  6. Install Go and protoc. In the /solutions/stickynoteapi/gRPC/Go/ directory, run the following command.

    sh INSTALL
    
  7. Load the new environment variables set by the INSTALL script.

    source $HOME/.bash_profile
    
  8. Start the Stickynotes server on the instance. In the /solutions/stickynoteapi/gRPC/Go/ directory, run the following command.

    sh SETUP
    
  9. In Xcode, edit StickyNotesViewController.m to change localhost to the external IP address of your Compute Engine instance from Step 2.

    // static NSString \* const kHostAddress = @"localhost";
    static NSString \* const kHostAddress = @"198.51.100.0";
    
  10. Select File > Save to save your changes.

  11. Select Product > Scheme > stickynotes to pick the correct scheme.

  12. Select Product > Run to build and start the client application.

  13. Enter a message in the text field and tap Return.

An image of a yellow sticky note with your message should replace the gray background.

Testing on remote server...

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Deleting the project

The easiest way to eliminate billing is to delete the project you created for the tutorial.

To delete the project:

  1. 在 GCP Console 中,转到“项目”页面。

    转到“项目”页面

  2. 在项目列表中,选择要删除的项目,然后点击删除项目选择项目名称旁边的复选框后,点击“删除项目”
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

Deleting instances

To delete a Compute Engine instance:

  1. 在 GCP Console 中,转到“虚拟机实例”页面。

    转到“虚拟机实例”页面

  2. 点击 要删除的实例旁边的复选框。
  3. 点击页面顶部的删除按钮以删除实例。

Deleting firewall rules for the default network

To delete a firewall rule:

  1. 在 GCP Console 中,转到“防火墙规则”页面。

    转到“防火墙规则”页面

  2. 点击要删除的防火墙规则旁边的复选框。
  3. 点击页面顶部的删除按钮以删除防火墙规则。

What's next

This sample demonstrates the basics of how to connect a mobile app to code running on Compute Engine over gRPC. To extend this sample into a real app, consider adding the following enhancements:

  • Add a static IP address to your server -- by default, the external address associated with a Compute Engine instance is transient. For a production app you should attach a static IP address to your instance. For more information, see Configuring an Instance’s IP Address.

  • Add load balancing and autoscaling -- handle traffic spikes gracefully by setting up a load balancer and autoscaler to spin up extra instances when demand grows, and to route traffic evenly across those instances. For more information, see Setting up HTTP(s) Load Balancing and Autoscaling Groups of Instances.

  • Consider other hosting options for your backend service -- Compute Engine offers the greatest degree of control over your virtual machine, but at the cost of you manually updating and managing your instance. For a discussion of other ways to host a mobile backend service on Cloud Platform, see Build mobile apps using Google Cloud Platform.

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Solutions