代码之家  ›  专栏  ›  技术社区  ›  Jono

Go例程及其并发问题

  •  2
  • Jono  · 技术社区  · 10 年前

    TL;DR接受并连接两组单独的连接。希望同时使用RPC执行此操作。

    我正在尝试在我的计算机上创建半分布式系统。我现在正在处理的这段代码有点像代理节点,换句话说,它总是接受来自某个端口的客户端连接。它也不断接受来自不同端口的后端节点连接。 我正试图找到一种同时倾听和服务两者的方法。我正在使用RPC,我尝试的方法是: 主要内容:

    func main(){  
     ...  
     rpc.Register(myInterface)  
     l, err := net.Listen("tcp", client_port)  
     if err != nil {...}  
     go handleClients(l)  
     node_l, err := net.Listen("tcp", node_port)  
     if err != nil{...}   
     go setUpIncomingNodes(node_l, chan)  
     for{// add nodes to a list from chan} 
    }
    

    并发功能:

    // Adds clients to be connected
    func handleClients(listener net.Listener){
     for{
      conn, err :=listener.Accept()
      if err != nil{...}
      // Starts up a blocking (on that thread) RPC connection
      go rpc.serveConn(conn)
     }
    }
    func setUpIncomingNodes(node_listener net.Listener, incoming_nodes chan<- net.Conn){
     for{
      conn, err := node_listener.Accept()
      if err != nil{...}
      incoming_nodes <- conn     
     }
    }
    

    问题是,在第二个节点出现之前,它不会为第一个节点服务。我不明白为什么。同时,似乎一次只能发生一个连接,但我认为RPC服务于不同的端口(因此不会阻止它)。非常感谢任何帮助。

    我试着跟随 this tutorial 但我发现情况太不同了,它也使用了不同版本的围棋。我使用两种类型的节点/连接,其中类型A需要通过代理提供给类型B。

    1 回复  |  直到 10 年前
        1
  •  1
  •   Jono    10 年前

    最后,我认为问题是我试图 通过 在听众中 Go例程 从而使每个go例程具有与主线程的依赖性。工作解决方案最终变得如此简单:

    func main(){
     ...
     node_ip_port := "127.0.0.1:9000"
     client_ip_port := "127.0.0.1:1000"
     nodeChan := make(chan net.Conn, 20)
    
     go func(ip_port string, nodeChan chan<- net.Conn) {
        l, err := net.Listen("tcp", node_ip)
        if err != nil {
            log.Fatal("Had an error connecting to node", err)
        }
        for {
            conn, _ := l.Accept()
            kvChan <- conn
        }
      }(node_ip_port, nodeChan)
    
     go func(ip_port string) {
        l, err := net.Listen("tcp", ip_port)
        if err != nil {
            log.Fatal("Had an error connecting to client", err)
        }
        for {
            conn, _ := l.Accept()
            go rpc.ServeConn(conn)
        }
      }(client_ip_port)
      // List of connected nodes
      nodeList := list.New()
      for {
        node := <-nodeChan
        nodeList.PushBack(node)
        // My RPC functions use the nodes in this list to serve :-)
      }
     }
    
    推荐文章
    Nisbo  ·  mqtt代理-aclfile
    7 年前
    Jono  ·  Go例程及其并发问题
    10 年前