type Server strung { quit chan bool }
func NewServer() *Server{
s := &Server{make(chan bool)}
go s.run()
return s
}
func (s *Server) run() {
for {
select {
case: <- s.quit:
fmt.Println("finishing task")
time.Sleep(time.Secod)
fmt.Println("task done")
s.quit <- true
return
case: <- time.After(time.Secod)
fmt.Println("running task")
}
}
}
func (s *Server) Stop() {
fmt.Println("server stoppint")
<- s.quit
fmt.Println("server stopped")
}
func main() {
s := NewServer()
time.Sleep(2 * time.Second)
s.Stop //会阻塞等待quit通知
}
首先我们来开发一个应用程序实现广播功能:
实现一个向其他服务发送消息的函数。
func sendMsg(msg, addr string) error {
conn, err := net.Dial("tcp", addr)
if err != nil {
return err
}
defer conn.Close()
_, err = fmt.Fprint(conn, msg)
return err
}
func broadcastMsg(msg string, addrs []string) error {
err := make(chan error)
for _, add := range addrs {
go func (adds string) {
err <- sendMsg(msg, addr)
fmt.Println("done")
}(adds)}
for _ = range addrs {
if err := <- err; err != nil {
return err
}
}
return nil
}
func main() {
addr := []string{"localhost:8080, "http://google.com"}
err := broadcastMsg("hi", addr)
time.Sleep(time.Second)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("消息发送成功")
}
func broadcasMsg(msg string, adds []string) error {
errc := make(chan error, len(addrs))
for _, addr := range addrs {
go func(addr string) {
errc <- sendMsg(msg, addr)
fmt.Println("done")
}(addr)
}
for _ = range addrs {
if err := <-errc; err != nil {
return err
}
}
return nil
}
func broadcastMsg(msg string, addrs []string) error {
errc := make(chan error)
quit := make(chan struct)
defer close(quit)
for _, addr := range addrs {
go func(addr string) {
select {
case errc <- sendMsg(msg, addr):
fmt.Println("done")
case <- quit:
fmt.Println("quit")
}
}(addr)
}
for _ = range addrs {
if err := <- errc; err != nil {
return err
}
}
return nil
}