Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

github.com/i-Pear/Distributed-Systems-Assignments/Assignment01

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/i-Pear/Distributed-Systems-Assignments/Assignment01

  • v0.0.0-20221016153045-d65c868a5c9a
  • Source
  • Go
  • Socket score

Version published
Created
Source

Origin Docs: https://m4q0j7d2yi.feishu.cn/docx/EZqfdEmrGo6JpWxu1ndc9yPvnhg

Analysis and design

Requirements

Design a distributed application that generates and displays current time in several machines: One server object/procedure/node generates the current time and displays it on local machines. Other two/more client objects/procedures/nodes get time to be displayed from the server, and display it in digital mode/per second or analogue mode/per minute. Requirements: Use RPC as the communication mechanism. Only authorized clients could get time from the server.

Design

Roles

Server: set up a rpc server and listen to a specified tcp port, return local time while receiving rpc calls

Clients: send rpc requests every second, and display the time returned by the server

Developing environments

I prefer to use GO for programming language, and use gRPC for rpc server implementation.

gRPC is a modern, open source, high-performance RPC framework that can run anywhere. It enables client and server applications to communicate transparently, and simplifies the building of connected systems.

gRPC uses protobuf for encoding messages. protobuf is one of the most popular libraries in production environments.

Message Formats

Message formats must be defined for server-client communications. Luckily, protobuf provides a user-friendly way to define it, and our design is also simple:

img

We declared a service named TimeService. In this model, the client simply sends a TimeRequest with a token, which will be used to authorize its permission. The server will return a TimeReply structure after receiving such a TimeRequest, where the "success" field indicates whether the request is valid or not, and the "server_time" field offers a time result in Unix time format (count of seconds passed from 1970-01-01).

Implement

Generate protobuf codes

We use the following command to generate code for populating, serializing, and retrieving TimeRequest and TimeReply message types:

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative protocol/protocol.proto

Token authorization

A token is used to verify the identities of clients. To make it easier, we simply agreed on a prefix "client_". For further security, it should be replaced by some encryption algorithms, such as AES.

The isValidToken() function is used to verify tokens:

func isValidToken(token string) bool {
   return strings.HasPrefix(token, "client_")
}

And the getToken() function is for generating tokens for clients:

func getToken() string {
   return "client_" + strconv.Itoa(rand.Int())
}

Server implementation

Firstly, we try to allocate the port specified by program arguments.

listen, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))

Then create a server and register the rpc function onto it:

timeServer := grpc.NewServer()
pb.RegisterTimeServiceServer(timeServer, &server{})

Client implementation

Firstly, we set up a connection to the server:

conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))

Then we initialize a client from the above connection:

client := pb.NewTimeServiceClient(conn)
ctx, cancel := context.WithCancel(context.Background())

Finally, simply call "client.GetTime()" as a local method, and print the formatted time on the screen:

response, err := c(ctx, &pb.TimeRequest{
   Token: getToken(),
})

timestr := time.Unix(response.GetServerTime(), 0).String()
fmt.Printf("Time from server: %s\n", timestr)

Deploying

We provide a Makefile script for quickly deploying:

.PHONY: client server

all:
   echo "Usage:"
   echo "Run client: make client"
   echo "Run server: make server"
client:
   go run client/client.go

server:
   go run server/server.go

proto:
   protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative protocol/protocol.proto

To run a server, you can just run:

make server

For clients, you can also simply run:

make client

For futher development, run the following command to update protobuf codes:

make proto

Testing

Start up a server on computer A (172.24.88.176):

img

Run client with the following command:

go run client/client.go 172.24.88.176:11451

After the client initialized its connection to the server, it prints time data received from the server:

img

Starting another client on another computer will display the same. And the server is also printing the times it sends to the client, with the clients' tokens:

img

Summary

RPC technology provides encapsulation of server-client connections, and calling remote functions is as easy as locally, which greatly facilitates the development of distributed programs.

Attachments

Opensource project: https://github.com/i-Pear/Distributed-Systems-Assignments

FAQs

Package last updated on 16 Oct 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc