github.com/godevsig/adaptiveservice@v0.9.23/examples/echo/server/messages.go (about) 1 package server 2 3 import ( 4 "fmt" 5 "sync/atomic" 6 "time" 7 8 as "github.com/godevsig/adaptiveservice" 9 ) 10 11 // MessageRequest is the message sent by client. 12 // Return MessageReply. 13 type MessageRequest struct { 14 Msg string 15 Num int32 16 } 17 18 // MessageReply is the message replied by server, 19 // with Num+1 and a signature of "yours echo.v1.0". 20 type MessageReply struct { 21 *MessageRequest 22 Signature string 23 } 24 25 // Handle handles msg. 26 func (msg *MessageRequest) Handle(stream as.ContextStream) (reply interface{}) { 27 si := stream.GetContext().(*sessionInfo) 28 msg.Msg = msg.Msg + "!" 29 msg.Num++ 30 atomic.AddInt64(&si.mgr.counter, 1) 31 time.Sleep(time.Second / 2) 32 return &MessageReply{msg, si.sessionName} 33 } 34 35 // SubWhoElseEvent is used for clients to subscribe who else event which 36 // reports new incoming connection to the server. 37 // Return string. 38 type SubWhoElseEvent struct{} 39 40 // Handle handles msg. 41 func (msg SubWhoElseEvent) Handle(stream as.ContextStream) (reply interface{}) { 42 si := stream.GetContext().(*sessionInfo) 43 ch := make(chan string, 1) 44 si.mgr.Lock() 45 si.mgr.subscribers[ch] = struct{}{} 46 si.mgr.Unlock() 47 go func() { 48 for { 49 addr := <-ch 50 if err := stream.Send(addr); err != nil { 51 si.mgr.Lock() 52 delete(si.mgr.subscribers, ch) 53 si.mgr.Unlock() 54 fmt.Println("channel deleted") 55 return 56 } 57 } 58 }() 59 return 60 } 61 62 // WhoElse reports all client addresses the server has so far. 63 // Return string. 64 type WhoElse struct{} 65 66 // Handle handles msg. 67 func (msg WhoElse) Handle(stream as.ContextStream) (reply interface{}) { 68 si := stream.GetContext().(*sessionInfo) 69 var addrs string 70 si.mgr.RLock() 71 for client := range si.mgr.clients { 72 addrs += " " + client 73 } 74 si.mgr.RUnlock() 75 return addrs 76 } 77 78 // MessageTimeout is for timeout test 79 type MessageTimeout struct{} 80 81 // Handle handles msg. 82 func (msg MessageTimeout) Handle(stream as.ContextStream) (reply interface{}) { 83 time.Sleep(10 * time.Second) 84 return as.OK 85 } 86 87 type sessionInfo struct { 88 sessionName string 89 mgr *statMgr 90 } 91 92 func (mgr *statMgr) onConnect(netconn as.Netconn) (stop bool) { 93 raddr := netconn.RemoteAddr().String() 94 fmt.Println("on connect from:", raddr) 95 mgr.Lock() 96 mgr.clients[raddr] = struct{}{} 97 mgr.Unlock() 98 99 go func() { 100 mgr.RLock() 101 for ch := range mgr.subscribers { 102 ch <- raddr 103 } 104 mgr.RUnlock() 105 }() 106 107 return false 108 } 109 110 func (mgr *statMgr) onDisconnect(netconn as.Netconn) { 111 raddr := netconn.RemoteAddr().String() 112 fmt.Println("on disconnect from:", raddr) 113 mgr.Lock() 114 delete(mgr.clients, raddr) 115 mgr.Unlock() 116 } 117 118 func (mgr *statMgr) onNewStream(ctx as.Context) { 119 fmt.Println("on new stream") 120 sessionName := fmt.Sprintf("yours echo.v1.0 from %d", atomic.AddInt32(&mgr.sessionNum, 1)) 121 ctx.SetContext(&sessionInfo{sessionName, mgr}) 122 } 123 124 var echoKnownMsgs = []as.KnownMessage{ 125 (*MessageRequest)(nil), 126 SubWhoElseEvent{}, 127 WhoElse{}, 128 MessageTimeout{}, 129 } 130 131 func init() { 132 as.RegisterType((*MessageRequest)(nil)) 133 as.RegisterType((*MessageReply)(nil)) 134 as.RegisterType(SubWhoElseEvent{}) 135 as.RegisterType(WhoElse{}) 136 as.RegisterType(MessageTimeout{}) 137 }