Skip to content
This repository has been archived by the owner on Dec 5, 2017. It is now read-only.

Client Tutorial

erikstmartin edited this page Sep 13, 2012 · 4 revisions

We are going to walk through creating a basic client to communicate with the TutorialService that we created in the previous tutorial. For more detailed information on clients please refer to the Clients Documentation page

As a first step you may want to check out the examples/client directory. We have also included the completed client in the examples/tutorials/client directory for your reference

Setup

First you need to create a directory and a .go file, define it as part of package main and import skynet and skynet/client as well as fmt because we want to output our result

package main

import (
	"github.com/bketelsen/skynet"
	"github.com/bketelsen/skynet/client"
	"fmt"
)

Creating your client

Setup

As with the service we need our Request and Response types. We are going to duplicate them here for simplicity, but ordinarily you would include a shared package that contains them.

type TutorialRequest struct {
  Value int
}

type TutorialResponse struct {
  Value int
}

Then we need our main function, which we'll go through piece by piece

func main(){
	config, _ := skynet.GetClientConfig()
	client := client.NewClient(config)

	service := client.GetService("TutorialService", "1", "Development", "")

  req := &TutorialRequest {
    Value: 1,
  }

  resp := &TutorialResponse{}

  err := service.Send(nil, "AddOne", req, resp)

  if err != nil {
    fmt.Println(err)
  } else {
    fmt.Println(resp.Value)
  }
}

Here we initialize a new Client Config, using our handy dandy skynet.GetClientConfig() which will parse options from the command line or Environment Variables for where to find doozer etc. For a full list of command line options view the Client Documentation page. You can initialize this yourself and supply all the options manually.

config, _ := skynet.GetClientConfig()

Next we ask skynet for a client and pass it our config. We will share this same client for all services we connect to.

client := client.NewClient(config)

Now that we have a skynet client we can ask it for a client for an individual service, you can do this for multiple services, all service clients will share the same pools to specific instances so that you don't have to worry about individual pools getting too big.

It takes 4 arguments. Any optional parameters if supplied with an empty string are considered as all/any. So not supplying a region will connect to any matching services in any region.

  • The name of the service
  • The version of the service you're requesting (optional)
  • The region of the service (optional)
  • The host of the service (optional)

Connection pools are managed for you to instances, and self-adjust as instances come online or are taken offline.

service := client.GetService("TutorialService", "1", "Development", "")

Then we create instances of our request and response object.

req := &TutorialRequest {
  Value: 1,
}

resp := &TutorialResponse{}

Time to make the request. Send takes 4 parameters.

  • a skynet.RequestInfo which stores the UUID you want for the request to be passed along, this can be nil if your services aren't using it.
  • the name of the RPC method to call
  • a request object, this should match the one defined on the service side.
  • a pointer to a response object that will be populated if an error does not occur
err := service.Send(nil, "AddOne", req, resp)

Let's get our response. We are just going to output an error if it occurs, if not the result of our RPC call.

if err != nil {
  fmt.Println(err)
} else {
  fmt.Println(resp.Value)
}

That's it

Our client in it's entirety looks like

package main

import (
  "github.com/bketelsen/skynet"
  "github.com/bketelsen/skynet/client"
  "fmt"
)

type TutorialRequest struct {
  Value int
}

type TutorialResponse struct {
  Value int
}

func main(){
	config, _ := skynet.GetClientConfig()
	client := client.NewClient(config)

	service := client.GetService("TutorialService", "1", "Development", "")

  req := &TutorialRequest {
    Value: 1,
  }

  resp := &TutorialResponse{}

  err := service.Send(nil, "AddOne", req, resp)

  if err != nil {
    fmt.Println(err)
  } else {
    fmt.Println(resp.Value)
  }
}

Running your client

Assuming you have doozer running and you have either set your SKYNET_DZHOST Environment Variable or you pass in the --doozer flag from the Client Documentation. If neither is supplied it will look for doozer running on it's default port at 127.0.0.1

You also need to have started your Tutorial Service

You can just do the following

go build
./client

skynet: 2012/09/12 20:46:21 {"*skynet.ClientConfig":{"IdleConnectionsToInstance":1,"MaxConnectionsToInstance":1,"IdleTimeout":0},"Time":"2012-09-12T20:46:21.299438-04:00"}
skynet: 2012/09/12 20:46:21 Connected to doozer at 192.168.126.101:8046
skynet: 2012/09/12 20:46:21 Discovered new doozer WE7CFFRW4CGMYL5O at 192.168.126.101:8046
skynet: 2012/09/12 20:46:21 Discovered service "TutorialService" at 127.0.0.1:9000
2

Moving on

There are more examples to check out in the examples/ directory of the codebase.