英文:
Simple RPC Call in Go
问题
我正在尝试使用Go中的RPC调用来创建一个最小的应用程序。从我的代码中可以看出,我大量借鉴了在线示例。
server.go:
package main
import (
[...]
)
type InfoDumper int
func (s *InfoDumper) Dump(request string, reply *string) error {
fmt.Println("Woooh imma deliverin stuff\n")
current_time := time.Now()
h := sha1.New()
var barray []byte
copy(barray, request)
hash_rq := h.Sum(barray)
*reply = request + "\n" + current_time.Format(time.ANSIC) + "\n" + string(hash_rq) + "\n"
return nil
}
func main() {
server := new(InfoDumper)
rpc.Register(server)
rpc.HandleHTTP()
l, e := net.Listen("tcp", "127.0.0.1:40000")
if e != nil {
fmt.Println(e)
}
http.Serve(l, nil)
}
client.go:
package main
import (
[...]
)
func main() {
client, e := rpc.Dial("tcp", "127.0.0.1:40000")
if e != nil {
fmt.Println(e)
} else {
fmt.Println("wooh server is ok")
}
in := bufio.NewReader(os.Stdin)
for {
line, _, _ := in.ReadLine()
request := string(line)
var reply string
e = client.Call("InfoDumper.Dump", request, &reply)
if e != nil {
fmt.Println("omg error!", e)
}
fmt.Println(reply)
}
}
我唯一看到的区别是我写的是http.Serve(l, nil)
而不是go http.Serve(l, nil)
;这是因为使用go
关键字会导致我的服务器立即终止。
InfoDump应该会回复一个副本,其中包含发送的内容、时间和请求的哈希值。
目前的情况是:
- 我在一个终端中运行server.go
- 我在另一个终端中运行client.go,大约一秒钟后会打印出"wooh server is ok"
- 我在客户端输入一些内容并按Enter键
- 要么什么都不会发生,要么在客户端打印出"rpc: client protocol error: unexpected EOF"
- 如果没有发生任何事情,终止服务器(即按下Control-C)会使客户端打印出上述错误
无论哪种情况,"Woooh imma deliverin stuff"都不会显示在服务器端...
这是在课堂上进行的,作为熟悉Go中的RPC的初步步骤,然后再进行更严肃的练习;所有其他学生都设法使这一步骤正常工作,并查看了这段代码,但是他们看不出与他们的代码有什么不同。
有人看到这段代码有什么问题吗?
英文:
I am trying to get a minimal application working using RPC calls in Go. I am heavily borrowing from the online example, as you can see from my code:
server.go:
<!-- language: lang-go -->
package main
import (
[...]
)
type InfoDumper int
func (s *InfoDumper) Dump(request string, reply *string) error {
fmt.Println("Woooh imma deliverin stuff\n")
current_time := time.Now()
h:= sha1.New()
var barray []byte
copy(barray, request)
hash_rq := h.Sum(barray)
*reply = request + "\n" + current_time.Format(time.ANSIC) + "\n" + string(hash_rq) + "\n"
return nil
}
func main() {
server := new(InfoDumper)
rpc.Register(server)
rpc.HandleHTTP()
l, e := net.Listen("tcp", "127.0.0.1:40000")
if e != nil {
fmt.Println(e)
}
http.Serve(l, nil)
}
client.go:
<!-- language: lang-go -->
package main
import (
[...]
)
func main() {
client, e := rpc.Dial("tcp", "127.0.0.1:40000")
if e!=nil {
fmt.Println(e)
} else {
fmt.Println("wooh server is ok")
}
in:= bufio.NewReader(os.Stdin)
for {
line, _, _ := in.ReadLine()
request := string(line)
var reply string
e = client.Call("InfoDumper.Dump", request, &reply)
if (e!=nil) {
fmt.Println("omg error!", e)
}
fmt.Println(reply)
}
}
The only difference I can see is that I wrote http.Serve(l, nil)
instead of go http.Serve(l, nil)
; this is because writing with go
makes my server terminate right away.
InfoDump is supposed to reply with a copy of whatever was sent, the time and hash of the request.
This is what's happening right now:
- I run server.go in a terminal
- I run client.go in another terminal, after a second or so "wooh server is ok" is printed
- I type something and hit Enter on the client's side
- either nothing happens, or "rpc: client protocol error: unexpected EOF" is printed on the client's side
- if nothing happened, terminating the server (ie hitting Control-C) makes the client print the error above
In either case, "Woooh imma deliverin stuff" is never displayed on the server's side...
This was done during class as a preliminary step to get acquainted with RPC in Go before going on to more serious exercises ; all the other students managed to get this step working, looked at this code and couldn't see the difference with theirs.
Does anyone see anything wrong with this code?
答案1
得分: 5
正如我在邮件列表回复中提到的,如果你想连接到使用HandleHTTP提供的RPC服务器,你需要使用DialHTTP。
我在邮件列表中还对你的代码做了一些其他的注释(包括样式:使用gofmt和MixedCaps,参考Effective Go,并确保在出现错误时退出)。
英文:
As I noted in my mailing list response, you will need to use DialHTTP if you want to connect to an RPC server that you have served using HandleHTTP.
I've made some other notes about your code (including styling: use gofmt and MixedCaps, per Effective Go, and be sure to bail out on errors) on the mailing list.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论