向一组主机发送带有确认的消息

huangapple go评论92阅读模式
英文:

Sending a message to set of hosts with acknowledgements

问题

这个函数位于主机上,当客户端想要向主机发送消息时调用。主机位于不同的位置,因此发送消息需要IP和端口,对吗?哪种机制可以帮助实现这个功能,net.dial()gob还是rpc

英文:

Function is like:

func Message(worker_ID int, message string, args *Args , reply *int) chan bool {
}

This function resides at host which is called by client when it want to send the message to hosts, hosts are located at different place, so both IP and port required to send message right? which mechanism can be helpful net.dial() or gob or rpc?

答案1

得分: 2

如果你想要简单的东西,那就看看 net/rpc,它将 gob 和网络封装成一个远程过程调用框架,应该能满足你的需求。

服务器

从文档中可以看到一个运行在 HTTP 上的服务器:

type Args struct {
        A, B int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
        *reply = args.A * args.B
        return nil
}

arith := new(Arith)
rpc.Register(arith)
rpc.HandleHTTP()
l, e := net.Listen("tcp", ":1234")
if e != nil {
        log.Fatal("listen error:", e)
}
go http.Serve(l, nil)

客户端

此时,客户端可以看到一个名为 "Arith" 的服务,其中包含方法 "Arith.Multiply"。要调用其中一个方法,先拨号服务器,然后进行调用。你还可以进行异步调用,结果将通过通道返回。

client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
if err != nil {
        log.Fatal("dialing:", err)
}

args := &server.Args{7,8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
        log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)

该框架的一个小特殊之处是,每个远程调用只能有一个输入参数和一个输出参数,这意味着你需要将所有参数都封装在一个 struct 中。

英文:

If you want something simple then check out net/rpc which wraps gob and networking into a remote procedure call framework which should do what you want.

Server

From the docs a server running over HTTP

type Args struct {
        A, B int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
        *reply = args.A * args.B
        return nil
}

arith := new(Arith)
rpc.Register(arith)
rpc.HandleHTTP()
l, e := net.Listen("tcp", ":1234")
if e != nil {
        log.Fatal("listen error:", e)
}
go http.Serve(l, nil)

Client

At this point, clients can see a service "Arith" with method "Arith.Multiply". To invoke one, dial the server then make a call. You can also make asynchronous calls where the result comes back in a channel.

client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
if err != nil {
        log.Fatal("dialing:", err)
}

args := &server.Args{7,8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
        log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)

A slight oddity of the framework is that each remote call can have only one input argument and one output argument which means that you need to wrap all your arguments in a struct.

答案2

得分: 1

//server.go将提供与主机通信和处理的接口

// workerDead(message string),发送消息并等待确认,如果没有确认表示worker已经死亡

package main
import(

"fmt"
"io"
"net"
"net/http"
"net/rpc"
"path"
"os"
)

type Flag int
type Args struct{
message string
}
func main() {

flag := new(Flag)
rpc.Register(flag)
rpc.HandleHTTP()
err := http.ListenAndServe(":1234", nil) //ListenAndServe使用给定的地址和处理程序启动HTTP服务器。
//处理程序通常为nil,这意味着使用DefaultServeMux。
if err != nil {
fmt.Println(err.Error())
}
}

//Worker计算主机的数量
func workerCount() int
{
return db.runCommand( { count: 'id' } ) //mongodb命令计算id的数量
}

// 从workers集合中的所有文档中返回字段id的不同值的数组
//在mongodb中,文档类似于rdbms表,集合类似于记录
func Worker(worker int) []string{
return db.runCommand ({ distinct: 'workers', key: 'id' } ) //mongodb命令获取列id的worker数组列表
}

func Message(worker int, message string, args *Args , reply *int) chan bool {

server, err :=rpc.Dial("tcp","192.168.23.12") //Serve Dials在这里发送消息到主机,这里的IP地址是主机的
if(err!=nil){
log.Fatal("Dialing", err)
}
var reply bool
args:=Args{message};
err = server.Call(args,&reply);
if(err!=nil){
log.Fatal("Dialing", err)
replaceWorker(); //没有来自worker的回复,然后调用replaceWorker
}
fmt.Println("Reply from host", reply);

}
return nil
}
//用新的worker替换特定项目的死亡worker
func replaceWorker(worker_id int,project_id int)
{
db.workers.update( //此查询使用id=worker_id(死亡worker的id)更新workers集合
{ _id: worker_id, _project_id: project_id },
{
//$set: { ' ': 'Warner' },
}

)

}

英文:

//server.go will provide the interface for communicating and handling hosts

// workerDead(message string), send the message and wait for ack, if no ack means worker dead

package
main
import(
   
"fmt"
"io"
"net"
"net/http"
"net/rpc"
"path"
"os"
)

type Flag int
type Args struct{
message string
}
func main() {

flag := new(Flag)
rpc.Register(flag)
rpc.HandleHTTP()
err := http.ListenAndServe(":1234", nil) //ListenAndServe starts an HTTP server with a given address and handler.
//The handler is usually nil, which means to use DefaultServeMux.
if err != nil {
fmt.Println(err.Error())
}
}

//Worker counts the number of hosts
func workerCount() int
{
return db.runCommand( { count: 'id' } ) //mongodb command to count the id
}

// Returns an array of the distinct values of field id from all documents in the workers collection
//In mongodb document is analogous to rdbms table and collection is record

func Worker(worker int) []string{
return db.runCommand ({ distinct: 'workers', key: 'id' } ) //mongodb command to get the array of list of
//workers for column id
}

func Message(worker int, message string, args *Args , reply *int) chan bool {


server, err :=rpc.Dial("tcp","192.168.23.12") //Serve Dials here to send message to host, IP address here is of host
if(err!=nil){
log.Fatal("Dialing", err)
}
var reply bool
args:=Args{message};
err = server.Call(args,&reply);
if(err!=nil){
log.Fatal("Dialing", err)
replaceWorker(); // No reply from worker then call to replace worker
}
fmt.Println("Reply from host", reply);

}
return nil
}
//Replace dead worker of particular project with fresh worker
func replaceWorker(worker_id int,project_id int)
{
db.workers.update( //this query updates workers collection with id=worker_id(id of dead worker)
   { _id: worker_id, _project_id: project_id },
   {
     //$set: { ' ': 'Warner' },
   }

)

}

huangapple
  • 本文由 发表于 2013年1月6日 15:00:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/14180097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定