示例#1
0
文件: main.go 项目: quintans/gomsg
func main() {
	// routing requests between server 1 and server 2
	server1 := gomsg.NewServer()
	server1.SetTimeout(time.Second)
	server1.Listen(":7777")
	server2 := gomsg.NewServer()
	server2.SetTimeout(time.Second)
	server2.Listen(":7778")
	// all (*) messages arriving to server 1 are routed to server 2
	gomsg.Route("*", server1, server2, time.Second,
		func(ctx *gomsg.Request) bool {
			fmt.Println("===>routing incoming msg:", string(ctx.Request()))
			return true
		},
		nil)

	// client 1 connects to server 1
	cli := gomsg.NewClient()
	cli.Connect("localhost:7777")

	cli2 := gomsg.NewClient()
	cli2.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		if m != MESSAGE {
			fmt.Printf("###> EXPECTED '%s'. RECEIVED '%s'.\n", MESSAGE, m)
		}
		fmt.Println("<=== processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("Hello %s", m), nil
	})
	// client 2 connects to server 2
	cli2.Connect("localhost:7778")

	var err error
	/*
		err = <-cli.Push("XPTO", "PUSH: One")
		if err != nil {
			fmt.Println("W: error:", err)
		}
	*/
	err = <-cli.Request("HELLO", MESSAGE, func(ctx gomsg.Response, r string, e error) {
		if r != REPLY {
			fmt.Printf("###> EXPECTED '%s'. RECEIVED '%s'.\n", REPLY, r)
		}
		fmt.Println("=================> reply:", r, e, "from", ctx.Connection().RemoteAddr())
	})
	if err != nil {
		fmt.Println("===> error:", err)
	}

	time.Sleep(time.Second * 3)
	cli.Destroy()
	time.Sleep(time.Millisecond * 100)
}
示例#2
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	server.Listen(":7777")
	cli := gomsg.NewClient()
	cli.Connect("localhost:7777")

	// this late server handler must propagate to the client
	server.Handle("XPTO", func(m string) {
		fmt.Println("<=== handling pull:", m)
	})
	time.Sleep(time.Millisecond * 100)

	e := <-cli.Publish("XPTO", "teste")
	if e != nil {
		fmt.Println("===> XPTO error:", e)
	}

	// this late client handler must propagate to the server
	cli.Handle("SUB", func(m string) {
		fmt.Println("<=== handling pub-sub:", m)
	})
	time.Sleep(time.Millisecond * 100)

	e = <-server.Publish("SUB", "teste")
	if e != nil {
		fmt.Println("===> SUB error:", e)
	}

	time.Sleep(time.Millisecond * 100)
}
示例#3
0
文件: main.go 项目: jmptrader/gomsg
func main() {
	cli := gomsg.NewClient().Connect("localhost:7777")
	time.Sleep(time.Millisecond * 100)

	// THE SERVER SHOWS UP AFTER THE CLIENT
	server := gomsg.NewServer()
	server.Handle("XPTO", func(m string) {
		fmt.Println("<=== handling pull:", m)
	})
	server.Listen(":7777")
	time.Sleep(time.Second)

	e := <-cli.Publish("XPTO", "teste")
	if e != nil {
		fmt.Println("===> error:", e)
	}

	/*
		cli.Handle("SUB", func(m string) {
			fmt.Println("<=== handling pub-sub:", m)
		})
		time.Sleep(time.Millisecond * 100)

		<-server.Publish("SUB", "teste")
	*/
	time.Sleep(time.Second)
}
示例#4
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	server.SetTimeout(time.Second)
	server.Listen(":7777")

	cli := gomsg.NewClient()
	cli.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing (1):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1]=%s", reverse(m)), nil
	})
	cli.Connect("localhost:7777")

	cli2 := gomsg.NewClient()
	cli2.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing (2):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[2]=%s", reverse(m)), nil
	})
	cli2.Connect("localhost:7777")

	time.Sleep(time.Millisecond * 100)
	// Warning: when requesting many in a server, the last response (end mark) will have a null connection
	server.RequestAll("REVERSE", "hello", func(ctx gomsg.Response, r string) {
		fmt.Println("===> reply:", r, ", last?", ctx.Last())
	}, time.Second)

	time.Sleep(time.Second * 2)
	fmt.Println("I: close...")
	cli.Destroy()
	time.Sleep(time.Second * 5)
}
示例#5
0
文件: bstar.go 项目: quintans/gomsg
//  This is our main task. First we bind/connect our sockets with our
//  peer and make sure we will get state messages correctly. We use
//  three sockets; one to publish state, one to subscribe to state, and
//  one for client requests/replies:
func NewBStar(primary bool, frontentAddr string, stateLocalAddr string, stateRemoteAddr string) *BStar {
	this := &BStar{}
	if primary {
		fmt.Println("I: Primary active, waiting for backup (passive)")
		this.state = STATE_PRIMARY
	} else {
		fmt.Println("I: Backup passive, waiting for primary (active)")
		this.state = STATE_BACKUP
	}

	this.quit = make(chan bool, 1)

	this.statepub = gomsg.NewClient().SetCodec(codec)

	this.statesub = gomsg.NewServer()
	this.statesub.SetCodec(codec)
	this.statesub.Handle("STATE", func(ctx *gomsg.Request) {
		state, _ := ctx.Reader().ReadUI8()
		//  Have state from our peer, execute as event
		if this.stateMachine(Event(state)) {
			this.quit <- true //  Error, so exit
		} else {
			this.updatePeerExpiry()
		}

	})

	this.frontend = gomsg.NewServer()
	this.frontend.SetCodec(codec)
	this.frontend.Handle("*", func(ctx *gomsg.Request) {
		//  Have a client request
		ok := !this.stateMachine(CLIENT_REQUEST)
		if ok {
			this.frontendHandler(this, ctx)
		} else {
			// rejects request
			ctx.Terminate()
		}
	})

	this.stateRemoteAddr = stateRemoteAddr
	this.stateLocalAddr = stateLocalAddr
	this.frontentAddr = frontentAddr

	return this
}
示例#6
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	server.Listen(":7777")

	ungrouped := 0
	cli := gomsg.NewClient()
	cli.Handle("HELLO", func(m string) {
		fmt.Println("<=== [0] processing:", m)
		ungrouped++
	})
	<-cli.Connect("localhost:7777")

	group1 := 0
	// Group HA subscriber
	cli1 := gomsg.NewClient()
	cli1.SetGroupId("HA")
	cli1.Handle("HELLO", func(m string) {
		fmt.Println("<=== [1] processing:", m)
		group1++
	})
	<-cli1.Connect("localhost:7777")

	// Group HA subscriber
	group2 := 0
	cli2 := gomsg.NewClient()
	cli2.SetGroupId("HA")
	cli2.Handle("HELLO", func(m string) {
		fmt.Println("<=== [2] processing:", m)
		group2++
	})
	<-cli2.Connect("localhost:7777")

	// Only one element of the group HA will process each message, alternately (round robin).
	server.Publish("HELLO", "one")
	wait()
	server.Publish("HELLO", "two")
	wait()
	server.Publish("HELLO", "three")
	wait()
	server.Publish("HELLO", "four")
	wait()

	if ungrouped != 4 {
		fmt.Println("ERROR: RECEIVED", ungrouped, "UNGROUPED EVENTS. EXPECTED 4.")
	}
	if group1 != 2 {
		fmt.Println("ERROR: RECEIVED", group1, "GROUP EVENTS. EXPECTED 2.")
	}
	if group2 != 2 {
		fmt.Println("ERROR: RECEIVED", group2, "GROUP EVENTS. EXPECTED 2.")
	}
	wait()
	server.Destroy()
	wait()
}
示例#7
0
文件: main.go 项目: jmptrader/gomsg
func main() {
	server := gomsg.NewServer()
	server.Listen(SERVER_PORT_1)
	defer server.Destroy()

	// client #1
	var received1 = 0
	cli1 := gomsg.NewClient()
	cli1.Handle(CONSUMER, func(m string) {
		fmt.Println("<<< client #1: received", m)
		if m == MESSAGE {
			received1++
		}
	})
	cli1.Connect(SERVER_1)
	defer cli1.Destroy()

	// client #2
	var received2 = 0
	cli2 := gomsg.NewClient()
	cli2.Handle(CONSUMER, func(m string) {
		fmt.Println("<<< client #2: received", m)
		if m == MESSAGE {
			received2++
		}
	})
	cli2.Connect(SERVER_1)
	defer cli2.Destroy()

	// give time to connect
	wait()

	// only one client will receive the message
	e := <-server.Push(CONSUMER, MESSAGE)
	if e != nil {
		fmt.Printf("Error: %s\n", e)
	}

	// a different client from before (round-robin)
	// will receive the message
	e = <-server.Push(CONSUMER, MESSAGE)
	if e != nil {
		fmt.Printf("Error: %s\n", e)
	}

	if received1 != 1 {
		fmt.Printf("Expected '%v', got '%v'\n", 1, received1)
	}

	if received2 != 1 {
		fmt.Printf("Expected '%v', got '%v'\n", 1, received2)
	}
}
示例#8
0
// NewDirectory creates a peer directory where all the clients connect to know about their peers
func NewDirectory(addr string, codec gomsg.Codec) *Directory {
	dir := &Directory{
		peers: make(map[net.Conn]string),
	}
	dir.server = gomsg.NewServer()
	dir.server.SetCodec(codec)
	dir.server.OnClose = func(c net.Conn) {
		// this will be called if a peer stops pinging
		fmt.Println("< Dir: peer", c.RemoteAddr(), "exited")

		dir.mu.Lock()
		defer dir.mu.Unlock()

		delete(dir.peers, c)
		dir.server.Publish("DROP", dir.peers[c])
	}
	// returns all the peer addresses
	dir.server.Handle("DIR", func(ctx *gomsg.Request) []string {
		fmt.Println("< Dir: DIRECTORY LIST")
		dir.mu.RLock()
		defer dir.mu.RUnlock()

		addrs := make([]string, len(dir.peers))
		i := 0
		for _, v := range dir.peers {
			addrs[i] = v
			i++
		}
		return addrs
	})
	dir.server.Handle("READY", func(ctx *gomsg.Request, port int) {
		c := ctx.Connection()
		addr := fmt.Sprint(c.RemoteAddr().(*net.TCPAddr).IP, ":", port)
		fmt.Println("< Dir: peer", addr, "PEER READY")

		dir.mu.Lock()
		defer dir.mu.Unlock()

		dir.peers[c] = addr

		dir.server.Publish("NEW", addr)
	})
	dir.server.Listen(addr)

	return dir
}
示例#9
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	server.SetTimeout(time.Second)
	server.Listen(":7777")

	cli := gomsg.NewClient()
	cli.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing (1):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1]=%s", reverse(m)), nil
	})
	cli.Connect("localhost:7777")

	/*
		cli2 := gomsg.NewClient()
		cli2.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
			fmt.Println("<=== processing (2):", m, "from", ctx.Connection().RemoteAddr())
			return fmt.Sprintf("[2]=%s", reverse(m)), nil
		})
		cli2.Connect("localhost:7777")

		// just to get in the way
		cli3 := gomsg.NewClient()
		cli3.Connect("localhost:7777")
	*/

	// ===============

	//time.Sleep(time.Millisecond * 100)
	fmt.Println("====> requesting...")
	<-server.Request("REVERSE", "hello", func(ctx gomsg.Response, r string) {
		fmt.Println("===> reply:", r)
	})
	/*
		server.RequestAll("REVERSE", "hello", func(ctx gomsg.Response, r string) {
			fmt.Println("===> reply:", ctx.Kind, r)
		}, time.Second)
	*/

	time.Sleep(time.Second * 2)
	fmt.Println("I: close...")
	cli.Destroy()
	time.Sleep(time.Second * 5)
}
示例#10
0
// NewNode creates a new Node
func NewNode() *Node {
	node := &Node{
		Wires:        gomsg.NewWires(gomsg.JsonCodec{}),
		dirs:         gomsg.NewWires(gomsg.JsonCodec{}),
		remoteDirs:   make([]*gomsg.Client, 0),
		peers:        make(map[string]*gomsg.Client),
		PingInterval: time.Second,
		PingFailures: 2,
		provides:     make(map[string]bool),
		providers:    make(map[string]*Provider),
	}
	node.local = gomsg.NewServer()
	// consecutive calls under 500 ms to "DIR/*"
	// will be consumed by the same directory node
	node.dirs.Stick("DIR/*", time.Millisecond*500)
	node.AddSendListener(0, func(event gomsg.SendEvent) {
		node.lazyConnect(event.Name)
	})
	return node
}
示例#11
0
func NewPeer(dirAddr string, bindAddr string, codec gomsg.Codec) *Peer {
	this := &Peer{
		codec: codec,
		peers: NewPeers(),
	}
	this.local = gomsg.NewServer()
	this.local.SetTimeout(time.Second)
	this.local.SetCodec(codec)
	this.local.Listen(bindAddr)

	this.dir = gomsg.NewClient().SetCodec(codec)
	this.dir.SetTimeout(time.Second)
	this.dir.OnConnect = func(w *gomsg.Wired) {
		this.dir.Handle("NEW", func(peerAddr string) {
			if peerAddr != this.self {
				fmt.Println("====>", bindAddr, ": new peer at", peerAddr)
				cli := gomsg.NewClient().SetCodec(codec)
				cli.Connect(peerAddr)
				this.peers.Put(peerAddr, cli)
			}
		})
		this.dir.Handle("DROP", func(peerAddr string) {
			this.peers.Remove(peerAddr)
		})

		port := this.local.Port()
		<-this.dir.Request("DIR", nil, func(ctx gomsg.Response, addrs []string) {
			this.self = fmt.Sprint(ctx.Connection().LocalAddr().(*net.TCPAddr).IP, ":", port)
			for _, v := range addrs {
				cli := gomsg.NewClient().SetCodec(this.codec)
				cli.Connect(v)
				this.peers.Put(v, cli)
			}
		})
		this.dir.Push("READY", port)
	}
	this.dir.Connect(dirAddr)

	return this
}
示例#12
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	server.SetTimeout(time.Second)
	server.Listen(":7777")

	cli := gomsg.NewClient()
	cli2 := gomsg.NewClient()

	fmt.Println("=========== STICKY PUSH =============")

	cli.Handle("PUSHING", func(ctx *gomsg.Request, m string) {
		fmt.Println("<=== processing PUSHING (1):", m, "from", ctx.Connection().RemoteAddr())
	})
	cli.Handle("NOISE", func(ctx *gomsg.Request, m string) {
		fmt.Println("<=== processing NOISE (21):", m, "from", ctx.Connection().RemoteAddr())
	})

	cli2.Handle("PUSHING", func(ctx *gomsg.Request, m string) {
		fmt.Println("<=== processing PUSHING (2):", m, "from", ctx.Connection().RemoteAddr())
	})
	cli2.Handle("NOISE", func(ctx *gomsg.Request, m string) {
		fmt.Println("<=== processing NOISE (22):", m, "from", ctx.Connection().RemoteAddr())
	})

	cli.Connect("localhost:7777")
	cli2.Connect("localhost:7777")

	wait()

	// note the FILTER_TOKEN at the end. This way we can define a range of Stickyness
	server.Stick("PUSH"+gomsg.FILTER_TOKEN, time.Millisecond*500)

	server.Push("PUSHING", "ping")
	wait()
	server.Push("PUSHING", "ping")
	wait()

	server.Push("NOISE", "---noise--- will provoque the rotation of the general cursor")
	wait()
	server.Push("PUSHING", "ping")
	wait()
	server.Push("NOISE", "---noise--- will provoque the rotation of the general cursor")
	wait()
	server.Push("PUSHING", "ping")
	time.Sleep(time.Second)
	server.Push("PUSHING", "change wire")
	wait()

	fmt.Println("=========== STICKY REQUEST =============")

	cli.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing REVERSE (1):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1]=%s", reverse(m)), nil
	})
	cli2.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing REVERSE (2):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[2]=%s", reverse(m)), nil
	})
	wait()

	server.Stick("REVERSE", time.Millisecond*500)
	// Warning: when requesting many in a server, the last response (end mark) will have a null connection
	var resultFn = func(ctx gomsg.Response, r string) {
		fmt.Println("===> reply:", r, ", last?", ctx.Last())
	}
	server.Request("REVERSE", "hello", resultFn)
	wait()
	server.Request("REVERSE", "world", resultFn)
	wait()
	server.Request("REVERSE", "ola", resultFn)
	wait()
	server.Request("REVERSE", "mundo", resultFn)
	time.Sleep(time.Second)
	server.Request("REVERSE", "change wire", resultFn)
	wait()

	time.Sleep(time.Second * 2)

	fmt.Println("I: close...")
	cli.Destroy()
	time.Sleep(time.Second * 5)
}
示例#13
0
文件: main.go 项目: jmptrader/gomsg
func main() {
	server := gomsg.NewServer()
	server.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("Hello %s", m), nil
	})
	server.Handle("XPTO", func(m string) {
		fmt.Println("<=== handling pull:", m)
	})
	server.Listen(":7777")

	cli := gomsg.NewClient()
	cli.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing (1):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1]=%s", reverse(m)), nil
	})
	cli.Handle("SUB", func(m string) {
		fmt.Println("<=== handling pub-sub:", m)
	})
	cli.Connect("localhost:7777")

	cli2 := gomsg.NewClient()
	cli2.Handle("REVERSE", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== processing (2):", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[2]=%s", reverse(m)), nil
	})
	cli2.Handle("SUB", func(m string) {
		fmt.Println("<=== handling pub-sub:", m)
	})
	cli2.Connect("localhost:7777")

	//var err error
	/*
		messages := []string{"Hello", "World", "Paulo"}
		for _, m := range messages {
			err = <-cli.Request("HELLO", m, func(ctx gomsg.IResponse, r string) {
				fmt.Println("===> reply:", r, "from", ctx.Connection().RemoteAddr())
			})
			if err != nil {
				fmt.Println("===> error:", err)
			}
		}
	*/

	time.Sleep(time.Millisecond * 100)
	// Warning: when requesting many in a server, the last response (end mark) will have a null connection
	server.RequestAll("REVERSE", "hello", func(ctx gomsg.Response, r string) {
		fmt.Println("===> reply:", r)
	}, time.Second)
	/*
		server.Request("REVERSE", "hello", func(ctx gomsg.IResponse, r string) {
			fmt.Println("===> reply:", r, "from", ctx.Connection().RemoteAddr())
		})
		server.Request("REVERSE", "hello", func(ctx gomsg.IResponse, r string) {
			fmt.Println("===> reply:", r, "from", ctx.Connection().RemoteAddr())
		})
		server.Request("REVERSE", "hello", func(ctx gomsg.IResponse, r string) {
			fmt.Println("===> reply:", r, "from", ctx.Connection().RemoteAddr())
		})
	*/

	//server.Publish("SUB", "PUB: La")
	/*
		err = <-cli.Publish("XPTO", "PUB: La")
		err = <-cli.Publish("XPTO", "PUB: Vida")
		err = <-cli.Publish("XPTO", "PUB: Loca")
	*/

	//cli.Push("XPTO", "One")

	/*
		err = <-cli.Push("XPTO", "PUSH: Two")
		err = <-cli.Push("XPTO", "PUSH: Three")
		err = <-cli.Push("XPTO", "PUSH: Four")
		time.Sleep(time.Millisecond * 100)

		err = <-cli.Push("FAIL", 123)
		fmt.Println("I: error:", err)
		if err == nil {
			fmt.Println("E: Should have returned an error")
		}
	*/

	time.Sleep(time.Millisecond * 100)
	fmt.Println("I: close...")
	cli.Destroy()
	time.Sleep(time.Millisecond * 100)
}
示例#14
0
文件: main.go 项目: quintans/gomsg
func main() {
	server := gomsg.NewServer()
	// keep alive
	var timeout = gomsg.NewTimeout(CLEAN_CYCLE, time.Second, func(o interface{}) {
		c := o.(net.Conn)
		fmt.Println("=====> killing connection from", c.RemoteAddr())
		server.Wires.Kill(c)
	})

	server.OnConnect = func(w *gomsg.Wired) {
		// starts monitoring
		timeout.Delay(w.Conn())
	}
	// for PING messages the server will reply immediatly,
	// without relaying the message to the clients.
	server.Route("*", time.Second,
		func(ctx *gomsg.Request) bool {
			// any message received, delays the timeout
			timeout.Delay(ctx.Connection())

			if ctx.Name == "PING" {
				ctx.SetReply([]byte("PONG"))
				return false
			}

			return true
		},
		nil)

	server.Listen(":7777")

	cli := gomsg.NewClient()
	cli.SetReconnectInterval(0)
	cli.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== [1] processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1] Hello %s", m), nil
	})
	cli.Connect("localhost:7777")

	// just to get in the way
	cli3 := gomsg.NewClient()
	cli3.SetReconnectInterval(0)
	cli3.Connect("localhost:7777")

	cli2 := gomsg.NewClient()
	cli2.SetReconnectInterval(0)
	cli2.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== [2] processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[2] Hello %s", m), nil
	})
	cli2.Connect("localhost:7777")

	<-cli3.RequestAll("HELLO", "World!", func(ctx gomsg.Response, r string, e error) {
		fmt.Println("===HELLO===> reply:", r, e, "from", ctx.Connection().RemoteAddr())
	})

	time.Sleep(time.Millisecond * 2000)
	<-cli3.RequestAll("HELLO", "World!", func(ctx gomsg.Response, r string, e error) {
		fmt.Println("===HELLO===> reply:", r, e, "from", ctx.Connection().RemoteAddr())
	})

	time.Sleep(time.Millisecond * 1000)
}
示例#15
0
文件: main.go 项目: quintans/gomsg
func main() {
	// all messages arriving to the server are routed to the clients
	server := gomsg.NewServer()
	server.Listen(":7777")
	server.Route("*", time.Second, nil, nil)

	cli := gomsg.NewClient()
	cli.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== [1] processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[1] Hello %s", m), nil
	})
	// sends multi reply
	cli.Handle("PIPE", func(ctx *gomsg.Request) {
		ctx.SendReply([]byte("\"Pipe #1\""))
		ctx.SendReply([]byte("\"Pipe #2\""))
		ctx.Terminate()
	})
	cli.Connect("localhost:7777")

	// just to get in the way
	cli3 := gomsg.NewClient()
	cli3.Connect("localhost:7777")

	cli2 := gomsg.NewClient()
	cli2.Handle("HELLO", func(ctx *gomsg.Request, m string) (string, error) {
		fmt.Println("<=== [2] processing:", m, "from", ctx.Connection().RemoteAddr())
		return fmt.Sprintf("[2] Hello %s", m), nil
	})
	cli2.Handle("PIPE", func(ctx *gomsg.Request) string {
		return "Pipe #201"
	})
	cli2.Connect("localhost:7777")

	<-cli3.RequestAll("HELLO", "World!", func(ctx gomsg.Response, r string, e error) {
		fmt.Println("===HELLO===> reply:", r, e, "from", ctx.Connection().RemoteAddr())
	})
	fmt.Println("===============")
	<-cli3.RequestAll("PIPE", nil, func(ctx gomsg.Response, s string) {
		fmt.Println("===PIPE===> reply:", ctx.Kind, string(ctx.Reply()), s)
	})
	fmt.Println("===============")
	<-cli3.Request("PIPE", nil, func(ctx gomsg.Response, s string) {
		fmt.Println("===PIPE===> reply:", ctx.Kind, string(ctx.Reply()), s)
	})
	/*
		cli.Request("HELLO", "World!", func(ctx gomsg.IResponse, r string, e error) {
			fmt.Println("=================> reply:", r, e, "from", ctx.Connection().RemoteAddr())
		})

		// check to see if the server is working
		server.Request("HELLO", "World!", func(ctx gomsg.IResponse, r string, e error) {
			fmt.Println("=================> reply:", r, e, "from", ctx.Connection().RemoteAddr())
		})
		server.Request("HELLO", "World!", func(ctx gomsg.IResponse, r string, e error) {
			fmt.Println("=================> reply:", r, e, "from", ctx.Connection().RemoteAddr())
		})
	*/

	time.Sleep(time.Millisecond * 100)
	cli.Destroy()
	time.Sleep(time.Millisecond * 100)
}
示例#16
0
文件: main.go 项目: quintans/gomsg
func main() {
	// all messages arriving to the server are routed to the clients
	server := gomsg.NewServer()
	server.Listen(":7777")
	server.Route("*", time.Second, nil, nil)

	ungrouped := 0
	cli := gomsg.NewClient()
	cli.Handle("HELLO", func(m string) {
		fmt.Println("<=== [0] processing:", m)
		ungrouped++
	})
	<-cli.Connect("localhost:7777")

	group1 := 0
	// Group HA subscriber
	cli1 := gomsg.NewClient()
	cli1.SetGroupId("HA")
	cli1.Handle("HELLO", func(m string) {
		fmt.Println("<=== [1] processing:", m)
		group1++
	})
	<-cli1.Connect("localhost:7777")

	// Group HA subscriber
	group2 := 0
	cli2 := gomsg.NewClient()
	cli2.SetGroupId("HA")
	cli2.Handle("HELLO", func(m string) {
		fmt.Println("<=== [2] processing:", m)
		group2++
	})
	<-cli2.Connect("localhost:7777")

	// publisher
	cli3 := gomsg.NewClient()
	<-cli3.Connect("localhost:7777")

	// Only one element of the group HA will process each message, alternately (round robin).
	//	cli3.Publish("HELLO", "Hello World!")
	//	cli3.Publish("HELLO", "Olá Mundo!")
	//	cli3.Publish("HELLO", "YESSSS!")
	cli3.Publish("HELLO", "one")
	wait()
	cli3.Publish("HELLO", "two")
	wait()
	cli3.Publish("HELLO", "three")
	wait()
	cli3.Publish("HELLO", "four")
	wait()

	if ungrouped != 4 {
		fmt.Println("ERROR: RECEIVED", ungrouped, "UNGROUPED EVENTS. EXPECTED 4.")
	}
	if group1 != 2 {
		fmt.Println("ERROR: RECEIVED", group1, "GROUP EVENTS. EXPECTED 2.")
	}
	if group2 != 2 {
		fmt.Println("ERROR: RECEIVED", group2, "GROUP EVENTS. EXPECTED 2.")
	}
	wait()
	cli.Destroy()
	wait()
}
示例#17
0
// NewServiceDirectory creates a peer ServiceDirectory where all the clients connect
// to know about service providers
func NewServiceDirectory(codec gomsg.Codec) *ServiceDirectory {
	dir := &ServiceDirectory{
		providers:    make(map[net.Conn]*Provider),
		PingInterval: time.Second,
		PingFailures: 2,
	}
	dir.server = gomsg.NewServer()
	dir.server.SetCodec(codec)
	dir.server.SetTimeout(time.Second * 5)

	dir.server.OnClose = func(c net.Conn) {

		dir.mu.Lock()
		defer dir.mu.Unlock()

		var provider = dir.providers[c]
		if provider != nil {
			fmt.Println("I: < Dir: peer", provider.Endpoint, "exited")
			delete(dir.providers, c)
			dir.server.Publish(C_DROPPEER, provider.Endpoint)
		} else {
			fmt.Println("I: < Dir: closing connection", c.RemoteAddr(), "for inexistente provider")
		}
	}
	// returns a list of endpoints (addresses) by service
	dir.server.Handle(S_ADDSERVICE, func(r *gomsg.Request, service string) error {
		var c = r.Connection()
		dir.mu.Lock()
		var provider = dir.providers[c]
		if provider != nil {
			fmt.Println("I: < Dir: S_ADDSERVICE service", provider.Endpoint, "->", service)
			provider.AddService(service)
		}
		dir.mu.Unlock()

		if provider != nil {
			var w = dir.server.Get(c)
			// notifies all nodes, but caller
			dir.server.SendSkip(w.Wire(), gomsg.REQALL, C_ADDSERVICE, Service{provider.Endpoint, service}, nil, time.Second)
		}

		return nil
	})

	dir.server.Handle(S_CANCELSERVICE, func(r *gomsg.Request, service string) error {
		var c = r.Connection()
		dir.mu.Lock()
		var provider = dir.providers[c]
		if provider != nil {
			fmt.Println("I: < Dir: S_CANCELSERVICE service", provider.Endpoint, "->", service)
			provider.RemoveService(service)
		}
		dir.mu.Unlock()

		if provider != nil {
			var w = dir.server.Get(c)
			// notifies all nodes, but caller
			dir.server.SendSkip(w.Wire(), gomsg.REQALL, C_CANCELSERVICE, Service{provider.Endpoint, service}, nil, time.Second)
		}

		return nil
	})

	dir.server.Handle(S_PEERREADY, func(r *gomsg.Request, provider Provider) []*Provider {
		var c = r.Connection()
		fmt.Println("< Dir: peer", c.RemoteAddr(), " S_PEERREADY:", provider)

		// will be using the IP from where the connection came
		provider.Endpoint = fmt.Sprintf("%s:%s", c.RemoteAddr().(*net.TCPAddr).IP, provider.Endpoint)

		dir.mu.Lock()
		defer dir.mu.Unlock()

		// Creates a shallow copy of all existing providers
		var copy = make([]*Provider, len(dir.providers))
		var i = 0
		for _, v := range dir.providers {
			copy[i] = v
			i++
		}

		// update directory
		dir.providers[c] = &provider

		// notifies all peers, but the caller
		var w = dir.server.Get(c)
		dir.server.SendSkip(w.Wire(), gomsg.REQALL, C_PEERREADY, provider, nil, time.Second)

		return copy
	})

	return dir
}