Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/rpc: Server.ServeHTTP assumes default http mux #13395

Closed
mbertschler opened this issue Nov 25, 2015 · 4 comments
Closed

net/rpc: Server.ServeHTTP assumes default http mux #13395

mbertschler opened this issue Nov 25, 2015 · 4 comments

Comments

@mbertschler
Copy link

mbertschler commented Nov 25, 2015

rpc.Server.ServeHTTP() calls http.Handle(rpcPath, server) and registers with http.DefaultServeMux. The second call to ServeHTTP() with the default names normally results in panic: http: multiple registrations for /_goRPC_. This means that if I want to start two different RPC endpoints on different ports I have to work around this library.

Solution with workaround

Playground link

package main

import (
    "fmt"
    "net"
    "net/http"
    "net/rpc"
)

func main() {
    Serve("one", ":2001")
    Serve("two", ":2002")
    Call(":2001")
    Call(":2002")
}

func Call(port string) {
    client, err := rpc.DialHTTP("tcp", port)
    if err != nil {
        fmt.Println(err)
    }
    var name string
    err = client.Call("Server.Name", struct{}{}, &name)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("Server name on port", port, "is", name)
}

func Serve(name, port string) {
    serv := rpc.NewServer()
    s := Server{name}
    serv.Register(&s)

    // ===== workaround ==========
    oldMux := http.DefaultServeMux
    mux := http.NewServeMux()
    http.DefaultServeMux = mux
    // ===========================

    serv.HandleHTTP(rpc.DefaultRPCPath, rpc.DefaultDebugPath)

    // ===== workaround ==========
    http.DefaultServeMux = oldMux
    // ===========================

    l, err := net.Listen("tcp", port)
    if err != nil {
        panic(err)
    }
    go http.Serve(l, mux)
}

// RPC Server
type Server struct {
    name string
}

func (s *Server) Name(arg struct{}, ret *string) error {
    *ret = s.name
    return nil
}

Maybe the API could be improved for a future version to support that use case without a workaround.
Like a ServeHTTPMux() that additionally takes a http.ServeMux

Go is go version go1.5.1 darwin/amd64

@vcastellm
Copy link

+1 this saved my ass, thanks

@rsc rsc changed the title net/rpc: Server.ServeHTTP() not usable with multiple http servers net/rpc: Server.ServeHTTP assumes default http mux Dec 28, 2015
@rsc rsc modified the milestones: Go1.7, Go1.7Early Dec 28, 2015
@gopherbot
Copy link
Contributor

CL https://golang.org/cl/20020 mentions this issue.

@bradfitz
Copy link
Contributor

bradfitz commented May 5, 2016

I think the net/rpc package is frozen. I don't think we'll be making any API additions to it. Sorry.

@bradfitz bradfitz closed this as completed May 5, 2016
@mbertschler
Copy link
Author

@bradfitz hmm okay, I understand. At least there is a pretty straightforward workaround, and it is probably not something a lot of people need.

@golang golang locked and limited conversation to collaborators May 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants