2017-07-28 80 views
0

我在Go工作,並且有點新來使用unix套接字。試圖尋找類似的問題,但找不到任何東西,所以如果這已被回答以前道歉。Golang unix套接字:在不同套接字上註冊RPC的相同類型?

我想使用unix套接字來模擬一組測試機器。我正在測試我的Raft實現,所以我想在不同的unix套接字上註冊同一類型的多個對象(一個大型結構)。但看一個簡單的例子,我寫,效果似乎不是我想要的:撥打不同的插座相同遠銷方法似乎是摺疊單個端口:

package main 

import (
    "net" 
    "fmt" 
    "net/rpc" 
    "log" 
    "sync" 
) 

type Server struct { 
    name string 
} 

type SpeakArgs struct { 
} 

type SpeakReply struct { 
    Success bool 
} 

type AddArgs struct { 
    A, B int 
} 

type AddReply struct { 
    Answer int 
    Success bool 
} 

func (s *Server) Add(args *AddArgs, reply *AddReply) error { 
    reply.Answer = args.A + args.B 
    reply.Success = true 
    return nil 
} 

func (s *Server) Speak(args *SpeakArgs, reply *SpeakReply) error { 
    fmt.Printf("My name is %v.\n", s.name) 
    reply.Success = true 
    return nil 
} 

func main() { 
    var wgMain, wgRegister, wgCall sync.WaitGroup 
    wgMain.Add(3) 
    wgRegister.Add(2) 
    wgCall.Add(1) 

    go func() { 
     server := &Server{name: "RICHARD"} 
     rpc.Register(server) 
     la, e := net.Listen("unix", "/tmp/example1.sock") 
     if e != nil { 
      log.Fatal("listen error:", e) 
     } 
     wgRegister.Done() 
     go rpc.Accept(la) 
     wgCall.Wait() 
     la.Close() 
     wgMain.Done() 
     fmt.Println("Server exited.") 
    }() 

    go func() { 
     server := &Server{name: "BENNY"} 
     rpc.Register(server) 
     lb, e := net.Listen("unix", "/tmp/example2.sock") 
     if e != nil { 
      log.Fatal("listen error:", e) 
     } 
     wgRegister.Done() 
     go rpc.Accept(lb) 
     wgCall.Wait() 
     lb.Close() 
     wgMain.Done() 
     fmt.Println("Server exited.") 
    }() 

    go func() { 
     wgRegister.Wait() 
     oneclient, err1 := rpc.Dial("unix", "/tmp/example1.sock") 
     twoclient, err2 := rpc.Dial("unix", "/tmp/example2.sock") 
     if err1 != nil { 
      log.Fatal("listen error:", err1) 
     } 
     if err2 != nil { 
      log.Fatal("listen error:", err2) 
     } 

     addArgs := &AddArgs{1, 2} 
     addReply := &AddReply{} 
     speakArgs := &SpeakArgs{} 
     speakReply := SpeakReply{} 
     oneclient.Call("Server.Add", addArgs, addReply) 
     oneclient.Call("Server.Speak", speakArgs, speakReply) 
     twoclient.Call("Server.Speak", speakArgs, speakReply) 

     fmt.Printf("Added numbers! %v + %v = %v.\n", addArgs.A, addArgs.B, addReply.Answer) 
     wgCall.Done() 
     oneclient.Close() 
     twoclient.Close() 
     wgMain.Done() 
     fmt.Println("Client exited.") 
    }() 
    wgMain.Wait() 
} 

我希望這同時打印理查德和BENNY在控制檯中Speak()在不同的客戶端上被調用時,而是打印其中一個兩次,看似隨機。有什麼我在這裏失蹤?輸出示例,這次RICHARD似乎出來了,但有時候是BENNY。

My name is RICHARD. 
My name is RICHARD. 
Added numbers! 1 + 2 = 3. 
Client exited. 
Server exited. 
Server exited. 

編輯:修復感謝Pavlo Strokov!如果沒有指定,rpc.Register默認爲DefaultServer,所以兩者都在同一個RPC服務器上註冊:更正是調用rpc.NewServer()並在那個服務器上註冊。

package main 

import (
    "net" 
    "fmt" 
    "net/rpc" 
    "log" 
    "sync" 
) 

type Server struct { 
    name string 
} 

type SpeakArgs struct { 
} 

type SpeakReply struct { 
    Success bool 
} 

type AddArgs struct { 
    A, B int 
} 

type AddReply struct { 
    Answer int 
    Success bool 
} 

func (s *Server) Add(args *AddArgs, reply *AddReply) error { 
    reply.Answer = args.A + args.B 
    reply.Success = true 
    return nil 
} 

func (s *Server) Speak(args *SpeakArgs, reply *SpeakReply) error { 
    fmt.Printf("My name is %v.\n", s.name) 
    reply.Success = true 
    return nil 
} 

func main() { 
    var wgMain, wgRegister, wgCall sync.WaitGroup 
    wgMain.Add(3) 
    wgRegister.Add(2) 
    wgCall.Add(1) 

    go func() { 
     rpcServer := rpc.NewServer() 
     server := &Server{name: "RICHARD"} 
     rpcServer.Register(server) 
     la, e := net.Listen("unix", "/tmp/example1.sock") 
     if e != nil { 
      log.Fatal("listen error:", e) 
     } 
     wgRegister.Done() 
     go rpcServer.Accept(la) 
     wgCall.Wait() 
     la.Close() 
     wgMain.Done() 
     fmt.Println("Server exited.") 
    }() 

    go func() { 
     rpcServer := rpc.NewServer() 
     server := &Server{name: "BENNY"} 
     rpcServer.Register(server) 
     lb, e := net.Listen("unix", "/tmp/example2.sock") 
     if e != nil { 
      log.Fatal("listen error:", e) 
     } 
     wgRegister.Done() 
     go rpcServer.Accept(lb) 
     wgCall.Wait() 
     lb.Close() 
     wgMain.Done() 
     fmt.Println("Server exited.") 
    }() 

    go func() { 
     wgRegister.Wait() 
     oneclient, err1 := rpc.Dial("unix", "/tmp/example1.sock") 
     twoclient, err2 := rpc.Dial("unix", "/tmp/example2.sock") 
     if err1 != nil { 
      log.Fatal("listen error:", err1) 
     } 
     if err2 != nil { 
      log.Fatal("listen error:", err2) 
     } 

     addArgs := &AddArgs{1, 2} 
     addReply := &AddReply{} 
     speakArgs := &SpeakArgs{} 
     speakReply := &SpeakReply{} 
     oneclient.Call("Server.Add", addArgs, addReply) 
     oneclient.Call("Server.Speak", speakArgs, speakReply) 
     twoclient.Call("Server.Speak", speakArgs, speakReply) 

     fmt.Printf("Added numbers! %v + %v = %v.\n", addArgs.A, addArgs.B, addReply.Answer) 
     wgCall.Done() 
     oneclient.Close() 
     twoclient.Close() 
     wgMain.Done() 
     fmt.Println("Client exited.") 
    }() 
    wgMain.Wait() 
} 

它打印

My name is RICHARD. 
My name is BENNY. 
Added numbers! 1 + 2 = 3. 
Client exited. 
Server exited. 
Server exited. 

回答

0

我想這是因爲你使用DefaultServer爲您的RPC服務器。相反,您應該爲每個服務器創建不同的服務器:RICHARD和BENNY。 請看看我的修改代碼在這裏按預期工作:RPC calls on one machine

+0

這工作,謝謝!詳細瞭解net/rpc :) – cort

+0

歡迎您! @cort –