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  }