Permalink
Browse files

Implement basics of a client and a server using jsonrpc.

  • Loading branch information...
nsf committed Jul 6, 2010
1 parent 0255a7c commit 6379b175e24872eb8a9ddd051defe0f6593740b9
Showing with 135 additions and 9 deletions.
  1. +42 −2 gocode.go
  2. +93 −7 gocodeserver.go
View
@@ -1,12 +1,51 @@
package main
import (
+// "os"
+// "io/ioutil"
+// "strings"
+ "rpc"
+ "rpc/jsonrpc"
+ "flag"
+ "fmt"
"os"
- "io/ioutil"
- "strings"
)
+var (
+ server = flag.Bool("s", false, "run a server instead of a client")
+)
+
+func serverFunc() {
+ acrRPC := new(ACR)
+ rpc.Register(acrRPC)
+ acrRPC.acr = NewACRServer("/tmp/acrserver")
+ defer os.Remove("/tmp/acrserver")
+ acrRPC.acr.Loop()
+}
+
+func clientFunc() {
+ // client
+ var args, reply int
+
+ client, err := jsonrpc.Dial("unix", "/tmp/acrserver")
+ if err != nil {
+ panic(err.String())
+ }
+ err = client.Call("ACR.Shutdown", &args, &reply)
+ if err != nil {
+ panic(err.String())
+ }
+ fmt.Printf("close request send\n")
+}
+
func main() {
+ flag.Parse()
+ if *server {
+ serverFunc()
+ } else {
+ clientFunc()
+ }
+ /*
if len(os.Args) != 2 {
panic("usage: ./gocode <apropos request>")
}
@@ -32,4 +71,5 @@ func main() {
}
}
print(res)
+ */
}
View
@@ -2,11 +2,49 @@ package main
import (
"net"
+ "rpc/jsonrpc"
"fmt"
+ "os"
+ "io"
+)
+
+//-------------------------------------------------------------------------
+// ACR type (used in RPC)
+//-------------------------------------------------------------------------
+
+type ACR struct {
+ acr *ACRServer
+}
+
+// shutdown request
+
+func (self *ACR) Shutdown(notused1 *int, notused2 *int) os.Error {
+ self.acr.Close()
+ return nil
+}
+
+// top-level imported module autocomplete request
+
+type ACRImportedAC struct {
+ file string
+ apropos string
+}
+
+type ACRImportedACReply struct {
+ completions []string
+}
+
+//-------------------------------------------------------------------------
+// Autocompletion Refactoring Server
+//-------------------------------------------------------------------------
+
+const (
+ ACR_CLOSE = iota
)
type ACRServer struct {
listener *net.UnixListener
+ cmd_in chan int
}
func NewACRServer(path string) *ACRServer {
@@ -20,23 +58,71 @@ func NewACRServer(path string) *ACRServer {
if err != nil {
panic(err.String())
}
+ self.cmd_in = make(chan int)
return self
}
-func (self *ACRServer) Loop() {
+func acceptConnections(in chan net.Conn, listener *net.UnixListener) {
for {
- c, err := self.listener.Accept()
+ c, err := listener.Accept()
if err != nil {
panic(err.String())
}
+ in <- c
+ }
+}
+
+type RPCDebugProxy struct {
+ rwc io.ReadWriteCloser
+ debugout io.Writer
+}
+
+func (self *RPCDebugProxy) Read(p []byte) (n int, err os.Error) {
+ tmp := make([]byte, len(p))
+ n, err = self.rwc.Read(tmp)
+ copy(p, tmp)
+ fmt.Fprintf(self.debugout, "Request:\n")
+ self.debugout.Write(tmp)
+ return
+}
+
+func (self *RPCDebugProxy) Write(p []byte) (n int, err os.Error) {
+ n, err = self.rwc.Write(p)
+ fmt.Fprintf(self.debugout, "Response:\n")
+ self.debugout.Write(p)
+ return
+}
- go func(c net.Conn) {
- fmt.Fprintf(c, "Preved!\n")
- c.Close()
- }(c)
+func (self *RPCDebugProxy) Close() os.Error {
+ return self.rwc.Close()
+}
+
+func NewRPCDebugProxy(rwc io.ReadWriteCloser, debugout io.Writer) *RPCDebugProxy {
+ self := new(RPCDebugProxy)
+ self.rwc = rwc
+ self.debugout = debugout
+ return self
+}
+
+func (self *ACRServer) Loop() {
+ conn_in := make(chan net.Conn)
+ go acceptConnections(conn_in, self.listener)
+ for {
+ // handle connections or server CMDs (currently one CMD)
+ select {
+ case c := <-conn_in:
+ go func(c net.Conn) {
+ jsonrpc.ServeConn(NewRPCDebugProxy(c, os.Stdout))
+ }(c)
+ case cmd := <-self.cmd_in:
+ switch cmd {
+ case ACR_CLOSE:
+ return
+ }
+ }
}
}
func (self *ACRServer) Close() {
- self.listener.Close()
+ self.cmd_in <- ACR_CLOSE
}

0 comments on commit 6379b17

Please sign in to comment.