duanke9540
duanke9540
2018-09-11 08:25

如何在nat中回复已接受的连接。订阅golang

已采纳

I am trying to make a tcp server in golang which accepts the connection, reads data and then publishes it via nats.Publish. But I also want to reply and close the connection inside the subsriber not in the main server script I see two possible ways: to publish connection or to make a new one in a subsriber, but I cannot realize either Thank you in advance

UPD A comment regarding I. Kozlovic answer: Not exactly what I wanted but may help :) I was writing about closing tcp connection - not a nats one and to close in another go process - not in the one it was accepted. But as I did not succeeded in it I could do the following basing on your answer: I can publish information I need via nats, process it and then reply with "OK. Close connection" and close the TCP connection in publisher which is a TCP server. However that would be great if I could reply not from this go process but from the another one. Its tricky I understand but I want to do the same I wrote in the previous message but with some modification. I have TCP server, it accepts connection and then connects nats and publishes message, another go process subscribed to this message processes input and then publishes its output to the third go process which processes its input and then replies "OK. Done. Close TCP connection" to the first go process.... :)

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dongy44342 dongy44342 3年前

    Based on your updated question, here is a possible approach. Note that the two extra processes are represented by go-routines here, but you would have them be separate processes in real case. I have also omitted error checking.

    // This represent what would be the last process in your
    // example.
    go func() {
        nc, _ := nats.Connect(nats.DefaultURL)
        nc.Subscribe("bar", func(m *nats.Msg) {
            fmt.Printf("Received request: %s, final stop, sending back to %v
    ", m.Data, m.Reply)
            nc.Publish(m.Reply, []byte("I'm here to help!"))
        })
        nc.Flush()
        runtime.Goexit()
    }()
    
    // This would be the in-between process that receives
    // the message triggered by the TCP accept
    go func() {
        nc, _ := nats.Connect(nats.DefaultURL)
        nc.Subscribe("foo", func(m *nats.Msg) {
            fmt.Printf("Received request: %s, forward to bar
    ", m.Data)
            nc.PublishRequest("bar", m.Reply, []byte(fmt.Sprintf("got %s", m.Data)))
        })
        nc.Flush()
        runtime.Goexit()
    }()
    
    // This would be your TCP server
    l, _ := net.Listen("tcp", "127.0.0.1:1234")
    for {
        c, _ := l.Accept()
        go func(c net.Conn) {
            // Close socket when done
            defer c.Close()
            // Connect to NATS
            nc, _ := nats.Connect(nats.DefaultURL)
            // Close NATS connection when done
            defer nc.Close()
            // Sends the request to first process. Note that this
            // has a timeout and so if no response is received, the
            // go-routine will exit, closing the TCP connection.
            reply, err := nc.Request("foo", []byte("help"), 10*time.Second)
            if err != nil {
                fmt.Printf("Got error: %v
    ", err)
            } else {
                fmt.Printf("Got reply: %s
    ", reply.Data)
            }
        }(c)
    }
    

    Note that is is usually not recommended to create very short lived NATS connections. You may want to reuse the NATS connection if that fits with your model.

    点赞 评论 复制链接分享

相关推荐