func SpawnConnector(address string, callback func(cellnet.CellID, interface{})) cellnet.CellID { cid := cellnet.Spawn(callback) // io goroutine go func() { if config.SocketLog { log.Printf("[socket] #connect %s %s\n", cid.String(), address) } conn, err := net.Dial("tcp", address) if err != nil { cellnet.Send(cid, EventConnectError{error: err}) if config.SocketLog { log.Println("[socket] connect failed", err.Error()) } return } cellnet.Send(cid, EventConnected{stream: NewPacketStream(conn)}) }() return cid }
func SpawnSession(stream cellnet.IPacketStream, callback func(cellnet.CellID, interface{})) cellnet.CellID { cid := cellnet.Spawn(callback) // io线程 go func() { var err error var pkt *cellnet.Packet for { // 从Socket读取封包并转为ltv格式 pkt, err = stream.Read() if err != nil { cellnet.Send(cid, EventClose{error: err}) break } cellnet.Send(cid, pkt) } }() return cid }
func SpawnAcceptor(address string, callback func(cellnet.CellID, interface{})) cellnet.CellID { cid := cellnet.Spawn(callback) // io goroutine go func() { if config.SocketLog { log.Printf("[socket] #listen %s %s\n", cid.String(), address) } ln, err := net.Listen("tcp", address) if err != nil { cellnet.Send(cid, EventListenError{error: err}) if config.SocketLog { log.Println("[socket] listen failed", err.Error()) } return } for { conn, err := ln.Accept() if err != nil { continue } cellnet.Send(cid, EventAccepted{stream: NewPacketStream(conn)}) } }() return cid }
func server() { disp := dispatcher.NewPacketDispatcher() dispatcher.RegisterMessage(disp, coredef.TestEchoACK{}, func(ses cellnet.CellID, content interface{}) { msg := content.(*coredef.TestEchoACK) log.Println("server recv:", msg.String()) cellnet.Send(ses, &coredef.TestEchoACK{ Content: proto.String("world"), }) }) ltvsocket.SpawnAcceptor("127.0.0.1:8001", dispatcher.PeerHandler(disp)) }
func spawnsend() { // no block spawn cell, msg function here cid := cellnet.Spawn(func(_ cellnet.CellID, cl interface{}) { switch v := cl.(type) { case string: log.Println(v) } }) cellnet.Send(cid, "hello world ") done <- true }
func joinNexus(addr string) { ltvsocket.SpawnConnector(addr, dispatcher.PeerHandler(Dispatcher)) dispatcher.RegisterMessage(Dispatcher, coredef.ConnectedACK{}, func(src cellnet.CellID, _ interface{}) { cellnet.Send(src, &coredef.RegionLinkREQ{ Profile: &coredef.Region{ ID: proto.Int32(cellnet.RegionID), Address: proto.String(config.Listen), }, }) }) dispatcher.RegisterMessage(Dispatcher, coredef.RegionLinkACK{}, func(src cellnet.CellID, content interface{}) { msg := content.(*coredef.RegionLinkACK) status := msg.GetStatus() if status.GetID() == cellnet.RegionID { log.Printf("[nexus] duplicate regionid: %d@%s", status.GetID(), status.GetAddress()) return } addRegion(src, status) for _, rg := range msg.GetAddressList() { //log.Printf("address: %d@%s", rg.GetID(), rg.GetAddress()) // 不能是自己 if rg.GetID() == cellnet.RegionID { continue } // 已经连上了, 不再连接 if GetRegion(rg.GetID()) != nil { continue } // 连接地址中的服务器 joinNexus(rg.GetAddress()) } }) }
func listenNexus() { listenAddr := config.Listen ltvsocket.SpawnAcceptor(listenAddr, dispatcher.PeerHandler(Dispatcher)) dispatcher.RegisterMessage(Dispatcher, coredef.RegionLinkREQ{}, func(ses cellnet.CellID, content interface{}) { msg := content.(*coredef.RegionLinkREQ) profile := msg.GetProfile() if profile.GetID() == cellnet.RegionID { log.Printf("duplicate regionid: %d@%s", profile.GetID(), profile.GetAddress()) return } addRegion(ses, profile) ack := coredef.RegionLinkACK{ AddressList: make([]*coredef.Region, 0), Status: &coredef.Region{ ID: proto.Int32(cellnet.RegionID), Address: proto.String(config.Listen), }, } IterateRegion(func(profile *RegionData) { ack.AddressList = append(ack.AddressList, profile.Region) }) cellnet.Send(ses, &ack) }) dispatcher.RegisterMessage(Dispatcher, coredef.ClosedACK{}, func(ses cellnet.CellID, _ interface{}) { removeRegion(ses) }) }
func client() { disp := dispatcher.NewPacketDispatcher() dispatcher.RegisterMessage(disp, coredef.TestEchoACK{}, func(ses cellnet.CellID, content interface{}) { msg := content.(*coredef.TestEchoACK) log.Println("client recv:", msg.String()) done <- true }) dispatcher.RegisterMessage(disp, coredef.ConnectedACK{}, func(ses cellnet.CellID, content interface{}) { cellnet.Send(ses, &coredef.TestEchoACK{ Content: proto.String("hello"), }) }) ltvsocket.SpawnConnector("127.0.0.1:8001", dispatcher.PeerHandler(disp)) }
func host() { // cellid: 0.1 acceptor // cellid: 0.2 connector // 开始测试的时机 nexus.Event.Add("OnAddRegion", func(args ...interface{}) { rd := args[0].(*nexus.RegionData) // client 连上来了 if rd.GetID() == 1 { log.Println("client connected", rd.GetID()) cellnet.Send(cellnet.NewCellID(1, 3), &coredef.TestEchoACK{ Content: proto.String("send to node"), }) // cellnet.Send(cellnet.NewCellID(1, 4), &coredef.TestEchoACK{ // Content: proto.String("send to callback"), // }) } }) }