Distributed programming: Difference between revisions

Content added Content deleted
(provided correct C# example)
(→‎{{header|Go}}: add gRPC)
Line 497: Line 497:


=={{header|Go}}==
=={{header|Go}}==
===Standard library net/rpc===
Package net/rpc in the Go standard library serializes data with the Go-native "gob" type. The example here sends only a single floating point number, but the package will send any user-defined data type, including of course structs with multiple fields.
Package net/rpc in the Go standard library serializes data with the Go-native "gob" type. The example here sends only a single floating point number, but the package will send any user-defined data type, including of course structs with multiple fields.

===Server===
'''Server:'''
<lang go>package main
<lang go>package main


Line 529: Line 531:
http.Serve(listener, nil)
http.Serve(listener, nil)
}</lang>
}</lang>
===Client===
'''Client:'''
<lang go>package main
<lang go>package main


Line 553: Line 555:
fmt.Printf("Tax on %.2f: %.2f\n", amount, tax)
fmt.Printf("Tax on %.2f: %.2f\n", amount, tax)
}</lang>
}</lang>
Client output:
{{out | Client output}}
<pre>
<pre>
Tax on 3.00: 0.15
Tax on 3.00: 0.15
</pre>
===gRPC===
See http://www.grpc.io/

The default serialization for gRPC is "protocol buffers." gRPC uses a .proto file to define an interface for the client and server. The .proto has its own syntax, independent of client and server implementation languages. Server and client programs here are Go however.

'''.proto:'''
<lang proto>syntax = "proto3";

service TaxComputer {
rpc Tax(Amount) returns (Amount) {}
}

message Amount {
int32 cents = 1;
}</lang>
'''Server:'''
<lang go>package main

import (
"errors"
"net"

"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"

"taxcomputer"
)

type taxServer struct {
rate float64
}

func (s *taxServer) Tax(ctx context.Context,
amt *taxcomputer.Amount) (*taxcomputer.Amount, error) {
if amt.Cents < 0 {
return nil, errors.New("Negative amounts not allowed")
}
return &taxcomputer.Amount{int32(float64(amt.Cents)*s.rate + .5)}, nil
}

func main() {
listener, err := net.Listen("tcp", ":1234")
if err != nil {
grpclog.Fatalf(err.Error())
}
grpcServer := grpc.NewServer()
taxcomputer.RegisterTaxComputerServer(grpcServer, &taxServer{.05})
grpcServer.Serve(listener)
}</lang>
'''Client:'''
<lang go>package main

import (
"fmt"

"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"

"taxcomputer"
)

func main() {
conn, err := grpc.Dial("localhost:1234", grpc.WithInsecure())
if err != nil {
grpclog.Fatalf(err.Error())
}
defer conn.Close()
client := taxcomputer.NewTaxComputerClient(conn)
amt := &taxcomputer.Amount{300}
tax, err := client.Tax(context.Background(), amt)
if err != nil {
grpclog.Fatalf(err.Error())
}
fmt.Println("Tax on", amt.Cents, "cents is", tax.Cents, "cents")
}</lang>
{{out | Client output}}
<pre>
Tax on 300 cents is 15 cents
</pre>
</pre>