// 客户端 func client() { pipe := cellnet.NewEventPipe() evq := socket.NewConnector(pipe).Start("127.0.0.1:7101") socket.RegisterSessionMessage(evq, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) { ack := &coredef.TestEchoACK{ Content: proto.String("hello"), } ses.Send(ack) log.Printf("client send: %s\n", ack.String()) }) socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) log.Println("client recv:", msg.String()) done <- true }) pipe.Start() <-done }
// 客户端 func client() { pipe := cellnet.NewEventPipe() evq := socket.NewConnector(pipe).Start("127.0.0.1:7101") socket.RegisterSessionMessage(evq, "coredef.SessionConnected", func(content interface{}, ses cellnet.Session) { signal.Done(1) ack := &coredef.TestEchoACK{ Content: "hello", } ses.Send(ack) log.Debugf("client send: %s\n", ack.String()) }) socket.RegisterSessionMessage(evq, "coredef.TestEchoACK", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) log.Debugln("client recv:", msg.String()) signal.Done(3) }) pipe.Start() signal.WaitAndExpect(1, "not connceted to router") signal.WaitAndExpect(2, "not recv client msg") signal.WaitAndExpect(3, "not recv server msg") }
func client() { pipe := cellnet.NewEventPipe() evq := socket.NewConnector(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(evq, "gamedef.TestEchoACK", func(content interface{}, ses cellnet.Session) { msg := content.(*gamedef.TestEchoACK) log.Debugln("client recv:", msg.String()) signal.Done(1) }) socket.RegisterSessionMessage(evq, "gamedef.SessionConnected", func(content interface{}, ses cellnet.Session) { ses.Send(&gamedef.TestEchoACK{ Content: "hello", }) }) pipe.Start() signal.WaitAndExpect(1, "not recv data") }
// 客户端连接上后, 主动断开连接, 确保连接正常关闭 func connClose() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe).Start("127.0.0.1:7235") socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(ses cellnet.Session, content interface{}) { // 连接上发包,告诉服务器不要断开 ses.Send(&coredef.TestEchoACK{ Content: proto.String("noclose"), }) }) socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(ses cellnet.Session, content interface{}) { msg := content.(*coredef.TestEchoACK) log.Println("client recv:", msg.String()) done <- 1 // 客户端主动断开 ses.Close() }) socket.RegisterSessionMessage(p, coredef.SessionClosed{}, func(ses cellnet.Session, content interface{}) { log.Println("close ok!") // 正常断开 done <- 2 }) pipe.Start() // 收到回包 if <-done != 1 { log.Panicln("test failed, not recv msg") } // 断开正常 if <-done != 2 { log.Panicln("test failed, not close") } fmt.Println("connected close test done!") }
func client() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe) p.SetName("client") p.Start("127.0.0.1:9201") socket.RegisterSessionMessage(p, "gamedef.SessionConnected", func(content interface{}, ses cellnet.Session) { rpc.Call(p, &gamedef.TestEchoACK{ Content: "rpc async call", }, func(msg *gamedef.TestEchoACK) { log.Debugln("client recv", msg.Content) signal.Done(1) }) }) pipe.Start() signal.WaitAndExpect(1, "not recv data") }
func StartGateConnector(pipe cellnet.EventPipe, addressList []string) { gateConnArray = make([]cellnet.Peer, len(addressList)) for index, addr := range addressList { conn := socket.NewConnector(pipe).Start(addr) gateConnArray[index] = conn gateIndex := new(int) *gateIndex = index // 广播 socket.RegisterSessionMessage(conn, coredef.UpstreamACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.UpstreamACK) // 生成派发的消息 // TODO 用PostData防止多重嵌套? // 调用已注册的回调 conn.CallData(&relayEvent{ SessionEvent: socket.NewSessionEvent(msg.GetMsgID(), ses, msg.Data), ClientID: msg.GetClientID(), }) }) } }
func server() { pipe := cellnet.NewEventPipe() qpsm := benchmark.NewQPSMeter(pipe, func(qps int) { log.Infof("QPS: %d", qps) }) evq := socket.NewAcceptor(pipe).Start(benchmarkAddress) socket.RegisterSessionMessage(evq, "gamedef.TestEchoACK", func(content interface{}, ses cellnet.Session) { if qpsm.Acc() > benchmarkSeconds { signal.Done(1) log.Infof("Average QPS: %d", qpsm.Average()) } ses.Send(&gamedef.TestEchoACK{}) }) pipe.Start() }
func runServer() { pipe := cellnet.NewEventPipe() p := socket.NewAcceptor(pipe).Start("127.0.0.1:7235") // 计数器, 应该按照connCount倍数递增 var counter int socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(ses cellnet.Session, content interface{}) { msg := content.(*coredef.TestEchoACK) counter++ log.Printf("No. %d: server recv: %v", counter, msg.String()) // 发包后关闭 ses.Send(&coredef.TestEchoACK{ Content: proto.String(msg.GetContent()), }) if msg.GetContent() != "noclose" { ses.Close() } }) pipe.Start() done <- 0 }
func client() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe).Start("127.0.0.1:7201") rpc.InstallClient(p) socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) { rpc.Call(p, &coredef.TestEchoACK{ Content: "rpc hello", }, func(msg *coredef.TestEchoACK) { log.Debugln("client recv", msg.Content) signal.Done(1) }) }) pipe.Start() signal.WaitAndExpect(1, "not recv data") }
// 后台服务器到router的连接 func StartBackendConnector(pipe cellnet.EventPipe, addressList []string, peerName string, svcName string) { routerConnArray = make([]cellnet.Peer, len(addressList)) if len(addressList) == 0 { log.Warnf("empty router address list") return } for index, addr := range addressList { peer := socket.NewConnector(pipe) peer.SetName(peerName) peer.(cellnet.Connector).SetAutoReconnectSec(defaultReconnectSec) peer.Start(addr) routerConnArray[index] = peer // 连上网关时, 发送自己的服务器名字进行注册 socket.RegisterSessionMessage(peer, "coredef.SessionConnected", func(content interface{}, ses cellnet.Session) { ses.Send(&coredef.RegisterRouterBackendACK{ Name: svcName, }) }) // 广播 socket.RegisterSessionMessage(peer, "coredef.UpstreamACK", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.UpstreamACK) // 生成派发的消息 // TODO 用PostData防止多重嵌套? // 调用已注册的回调 peer.CallData(&relayEvent{ SessionEvent: socket.NewSessionEvent(msg.MsgID, ses, msg.Data), ClientID: msg.ClientID, }) }) } }
// 多连接收封包后被服务器关闭, 确保收到封包 func multiConn() { pipe := cellnet.NewEventPipe() // 同步量 var endAcc sync.WaitGroup // 启动N个连接 for i := 0; i < connCount; i++ { endAcc.Add(1) p := socket.NewConnector(pipe).Start("127.0.0.1:7235") p.SetName(fmt.Sprintf("%d", i)) socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(ses cellnet.Session, content interface{}) { msg := content.(*coredef.TestEchoACK) log.Println("client recv:", msg.String()) // 正常收到 endAcc.Done() }) socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(ses cellnet.Session, content interface{}) { id, _ := strconv.Atoi(ses.FromPeer().Name()) // 连接上发包 ses.Send(&coredef.TestEchoACK{ Content: proto.String(fmt.Sprintf("data#%d", id)), }) }) } pipe.Start() // 等待完成 endAcc.Wait() fmt.Println("multi connection close test done!") }
// 客户端连接上后, 主动断开连接, 确保连接正常关闭 func testConnActiveClose() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) { signal.Done(1) // 连接上发包,告诉服务器不要断开 ses.Send(&coredef.TestEchoACK{ Content: proto.String("noclose"), }) }) socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) log.Debugln("client recv:", msg.String()) signal.Done(2) // 客户端主动断开 ses.Close() }) socket.RegisterSessionMessage(p, coredef.SessionClosed{}, func(content interface{}, ses cellnet.Session) { log.Debugln("close ok!") // 正常断开 signal.Done(3) }) pipe.Start() signal.WaitAndExpect(1, "TestConnActiveClose not connected") signal.WaitAndExpect(2, "TestConnActiveClose not recv msg") signal.WaitAndExpect(3, "TestConnActiveClose not close") }
func client() { pipe := cellnet.NewEventPipe() evq := socket.NewConnector(pipe).Start(benchmarkAddress) socket.RegisterSessionMessage(evq, "gamedef.TestEchoACK", func(content interface{}, ses cellnet.Session) { ses.Send(&gamedef.TestEchoACK{}) }) socket.RegisterSessionMessage(evq, "gamedef.SessionConnected", func(content interface{}, ses cellnet.Session) { ses.Send(&gamedef.TestEchoACK{}) }) pipe.Start() }
// 接收封包后被断开 func testRecvDisconnected() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) { // 连接上发包 ses.Send(&coredef.TestEchoACK{ Content: proto.String("data"), }) signal.Done(1) }) socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) log.Debugln("client recv:", msg.String()) signal.Done(2) }) socket.RegisterSessionMessage(p, coredef.SessionClosed{}, func(content interface{}, ses cellnet.Session) { // 断开 signal.Done(3) }) pipe.Start() signal.WaitAndExpect(1, "TestRecvDisconnected not connected") signal.WaitAndExpect(2, "TestRecvDisconnected not recv msg") signal.WaitAndExpect(3, "TestRecvDisconnected not closed") }
func InstallServer(p cellnet.Peer) { // 服务端 socket.RegisterSessionMessage(p, "coredef.RemoteCallREQ", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.RemoteCallREQ) p.CallData(&response{ ses: ses, req: msg, }) }) }
func InstallClient(p cellnet.Peer) { // 请求端 socket.RegisterSessionMessage(p, coredef.RemoteCallACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.RemoteCallACK) c := getCall(msg.GetCallID()) if c == nil { return } c.done(msg) }) }
// 网关服务器 func gateServer() { gate.DebugMode = true pipe := cellnet.NewEventPipe() gate.StartBackendAcceptor(pipe, "127.0.0.1:7201") gate.StartClientAcceptor(pipe, "127.0.0.1:7101") socket.RegisterSessionMessage(gate.ClientAcceptor, coredef.SessionAccepted{}, func(content interface{}, ses cellnet.Session) { log.Println("client accepted", ses.ID()) }) pipe.Start() <-done }
func server() { pipe := cellnet.NewEventPipe() evq := socket.NewAcceptor(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(evq, "gamedef.TestEchoACK", func(content interface{}, ses cellnet.Session) { msg := content.(*gamedef.TestEchoACK) log.Debugln("server recv:", msg.String()) ses.Send(&gamedef.TestEchoACK{ Content: msg.String(), }) }) pipe.Start() }
func server() { pipe := cellnet.NewEventPipe() evq := socket.NewAcceptor(pipe).Start("127.0.0.1:7234") socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) log.Println("server recv:", msg.String()) ses.Send(&coredef.TestEchoACK{ Content: proto.String(msg.String()), }) }) pipe.Start() }
// 注册连接消息 func RegisterMessage(eq cellnet.EventQueue, msgName string, userHandler func(interface{}, Response)) { if needRegisterServer { // 服务端 socket.RegisterSessionMessage(eq, "gamedef.RemoteCallREQ", func(content interface{}, ses cellnet.Session) { msg := content.(*gamedef.RemoteCallREQ) eq.CallData(&response{ ses: ses, req: msg, }) }) needRegisterServer = false } msgMeta := cellnet.MessageMetaByName(msgName) eq.RegisterCallback(msgMeta.ID, func(data interface{}) { if ev, ok := data.(*response); ok { rawMsg, err := cellnet.ParsePacket(&cellnet.Packet{ MsgID: ev.req.MsgID, Data: ev.req.Data, }, msgMeta.Type) if err != nil { log.Errorln("unmarshaling error:", err) return } userHandler(rawMsg, ev) } }) }
func runServer() { pipe := cellnet.NewEventPipe() p := socket.NewAcceptor(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(p, "gamedef.TestEchoACK", func(content interface{}, ses cellnet.Session) { msg := content.(*gamedef.TestEchoACK) // 发包后关闭 ses.Send(&gamedef.TestEchoACK{ Content: msg.Content, }) if msg.Content != "noclose" { ses.Close() } }) pipe.Start() }
func runServer() { pipe := cellnet.NewEventPipe() p := socket.NewAcceptor(pipe).Start("127.0.0.1:7201") socket.RegisterSessionMessage(p, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.TestEchoACK) // 发包后关闭 ses.Send(&coredef.TestEchoACK{ Content: proto.String(msg.GetContent()), }) if msg.GetContent() != "noclose" { ses.Close() } }) pipe.Start() }
func client() { pipe := cellnet.NewEventPipe() p := socket.NewConnector(pipe).Start("127.0.0.1:7234") rpc.InstallClient(p) socket.RegisterSessionMessage(p, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) { rpc.Call(p, &coredef.TestEchoACK{ Content: proto.String("rpc hello"), }, func(msg *coredef.TestEchoACK) { log.Println("client recv", msg.GetContent()) done <- true }) }) pipe.Start() }
func newRequest(evq cellnet.EventQueue, args interface{}, callback interface{}) (*request, interface{}) { needRegisterClientGuard.Lock() if needRegisterClient { // 请求端 socket.RegisterSessionMessage(evq, "gamedef.RemoteCallACK", func(content interface{}, ses cellnet.Session) { msg := content.(*gamedef.RemoteCallACK) c := getCall(msg.CallID) if c == nil { return } c.done(msg) }) needRegisterClient = false } needRegisterClientGuard.Unlock() req := &request{} funcType := reflect.TypeOf(callback) req.replyType = funcType.In(0) req.callback = reflect.ValueOf(callback) pkt, _ := cellnet.BuildPacket(args) addCall(req) return req, &gamedef.RemoteCallREQ{ MsgID: pkt.MsgID, Data: pkt.Data, CallID: req.id, } }
// 开启后台服务器的侦听通道 func StartBackendAcceptor(pipe cellnet.EventPipe, address string, peerName string) { BackendAcceptor = socket.NewAcceptor(pipe) BackendAcceptor.SetName(peerName) // 默认开启并发 BackendAcceptor.EnableConcurrenceMode(true) // 收到后端服务器发来的注册, 标示连接 socket.RegisterSessionMessage(BackendAcceptor, "coredef.RegisterRouterBackendACK", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.RegisterRouterBackendACK) registerBackend(ses, msg.Name) }) // 断开连接时, 刷新路由 socket.RegisterSessionMessage(BackendAcceptor, "coredef.SessionClosed", func(content interface{}, ses cellnet.Session) { closeBackend(ses) }) // 关闭客户端连接 socket.RegisterSessionMessage(BackendAcceptor, "coredef.CloseClientACK", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.CloseClientACK) if msg.ClientID == 0 { // 关闭所有客户端 FrontendAcceptor.IterateSession(func(ses cellnet.Session) bool { if DebugMode { log.Debugf("backend->client, close clientid %d", msg.ClientID) } ses.Close() return true }) } else { // 关闭指定客户端 clientSes := FrontendAcceptor.GetSession(msg.ClientID) // 找到连接并关闭 if clientSes != nil { if DebugMode { log.Debugf("backend->client, close clientid %d", msg.ClientID) } clientSes.Close() } else if DebugMode { log.Debugf("backend->client, client not found, close failed, clientid %d", msg.ClientID) } } }) // 广播 socket.RegisterSessionMessage(BackendAcceptor, "coredef.DownstreamACK", func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.DownstreamACK) pkt := &cellnet.Packet{ MsgID: msg.MsgID, Data: msg.Data, } if len(msg.ClientID) == 0 { // 广播给所有客户端 FrontendAcceptor.IterateSession(func(ses cellnet.Session) bool { if DebugMode { log.Debugf("backend->client, msgid: %d clientid %d", msg.MsgID, msg.ClientID) } ses.RawSend(pkt) return true }) } else { // 指定客户端发送 for _, clientid := range msg.ClientID { clientSes := FrontendAcceptor.GetSession(clientid) if clientSes != nil { if DebugMode { log.Debugf("backend->client, msg: %s(%d) clientid: %d", getMsgName(msg.MsgID), msg.MsgID, msg.ClientID) } clientSes.RawSend(pkt) } else if DebugMode { log.Debugf("backend->client, client not found, msg: %s(%d) clientid: %d", getMsgName(msg.MsgID), msg.MsgID, msg.ClientID) } } } }) BackendAcceptor.Start(address) }
// 开启后台服务器的侦听通道 func StartBackendAcceptor(pipe cellnet.EventPipe, address string) { BackendAcceptor = socket.NewAcceptor(pipe) // 关闭客户端连接 socket.RegisterSessionMessage(BackendAcceptor, coredef.CloseClientACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.CloseClientACK) if msg.ClientID == nil { // 关闭所有客户端 ClientAcceptor.IterateSession(func(ses cellnet.Session) bool { if DebugMode { log.Debugf("[gate] backend->client, close clientid %d", msg.GetClientID()) } ses.Close() return true }) } else { // 关闭指定客户端 clientSes := ClientAcceptor.GetSession(msg.GetClientID()) // 找到连接并关闭 if clientSes != nil { if DebugMode { log.Debugf("[gate] backend->client, close clientid %d", msg.GetClientID()) } clientSes.Close() } else if DebugMode { log.Debugf("[gate] backend->client, client not found, close failed, clientid %d", msg.GetClientID()) } } }) // 广播 socket.RegisterSessionMessage(BackendAcceptor, coredef.DownstreamACK{}, func(content interface{}, ses cellnet.Session) { msg := content.(*coredef.DownstreamACK) pkt := &cellnet.Packet{ MsgID: msg.GetMsgID(), Data: msg.Data, } if msg.ClientID == nil { // 广播给所有客户端 ClientAcceptor.IterateSession(func(ses cellnet.Session) bool { if DebugMode { log.Debugf("[gate] backend->client, msgid: %d clientid %d", msg.GetMsgID(), msg.GetClientID()) } ses.RawSend(pkt) return true }) } else { // 指定客户端发送 for _, clientid := range msg.ClientID { clientSes := ClientAcceptor.GetSession(clientid) if clientSes != nil { if DebugMode { log.Debugf("[gate] backend->client, msgid: %d clientid %d", msg.GetMsgID(), msg.GetClientID()) } clientSes.RawSend(pkt) } else if DebugMode { log.Debugf("[gate] backend->client, client not found, msgid: %d clientid %d", msg.GetMsgID(), msg.GetClientID()) } } } }) BackendAcceptor.Start(address) }