Просто RPC повикване в Go

Опитвам се да накарам минимално приложение да работи с помощта на RPC повиквания в Go. Заимствам много от онлайн пример, както можете да видите от моя код :

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: грешка в протокола на клиента: неочакван EOF"
  • ако нищо не се случи, прекратяването на сървъра (т.е. натискането на Control-C) кара клиента да отпечата горната грешка

И в двата случая „Woooh imma deliverin stuff“ никога не се показва от страната на сървъра...

Това беше направено по време на класа като предварителна стъпка за запознаване с RPC в Go, преди да преминете към по-сериозни упражнения; всички останали ученици успяха да накарат тази стъпка да работи, погледнаха този код и не можаха да видят разликата с техния.

Някой вижда ли нещо нередно в този код?


person Peniblec    schedule 04.12.2013    source източник
comment
Първа стъпка: Не пренебрегвайте грешките, върнати от ReadLine.   -  person Volker    schedule 04.12.2013
comment
@Volker: остави по-голямата част от проверката на грешките за краткост; в случай на ReadLine (и всички други извиквания наистина, с изключение на client.Call), не се връща грешка (==нула).   -  person Peniblec    schedule 04.12.2013


Отговори (1)


Както отбелязах в моя отговор на пощенския списък, ще трябва да използвайте DialHTTP, ако искате да се свържете към RPC сървър, който сте обслужвали чрез HandleHTTP.

Направих някои други бележки относно вашия код (включително стилизиране: използвайте gofmt и MixedCaps, според Effective Go и не забравяйте да се спасявате от грешки) в пощенския списък.

person Kyle Lemons    schedule 04.12.2013