github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/core/node_net.go (about) 1 package core 2 3 import ( 4 "fmt" 5 "github.com/15mga/kiwi" 6 "github.com/15mga/kiwi/ds" 7 "github.com/15mga/kiwi/network" 8 "github.com/15mga/kiwi/util" 9 "github.com/15mga/kiwi/worker" 10 "math/rand" 11 "net" 12 ) 13 14 type ( 15 NodeOption func(opt *nodeOption) 16 nodeOption struct { 17 ip string 18 port int 19 connType NodeConnType 20 selector NodeDialerSelector 21 } 22 NodeConnType uint8 23 ) 24 25 type NodeDialerSelector func(set *ds.Set2Item[kiwi.TSvc, int64, kiwi.INodeDialer]) (int64, *util.Err) 26 27 const ( 28 Tcp NodeConnType = iota 29 Udp 30 ) 31 32 func NodeType(t NodeConnType) NodeOption { 33 return func(opt *nodeOption) { 34 opt.connType = t 35 } 36 } 37 38 func NodeIp(ip string) NodeOption { 39 return func(opt *nodeOption) { 40 opt.ip = ip 41 } 42 } 43 44 func NodePort(port int) NodeOption { 45 return func(opt *nodeOption) { 46 opt.port = port 47 } 48 } 49 50 func NodeSelector(selector NodeDialerSelector) NodeOption { 51 return func(opt *nodeOption) { 52 opt.selector = selector 53 } 54 } 55 56 func InitNodeNet(opts ...NodeOption) { 57 kiwi.SetNode(NewNodeNet(opts...)) 58 } 59 60 func NewNodeNet(opts ...NodeOption) kiwi.INode { 61 opt := &nodeOption{ 62 connType: Tcp, 63 selector: func(set *ds.Set2Item[kiwi.TSvc, int64, kiwi.INodeDialer]) (int64, *util.Err) { 64 i := rand.Intn(set.Count()) 65 dialer, _ := set.GetWithIdx(i) 66 return dialer.NodeId(), nil 67 }, 68 } 69 for _, o := range opts { 70 o(opt) 71 } 72 n := &nodeNet{ 73 option: opt, 74 nodeBase: newNodeBase(), 75 svcToDialer: ds.NewKSet2[kiwi.TSvc, int64, kiwi.INodeDialer](8, func(dialer kiwi.INodeDialer) int64 { 76 return dialer.NodeId() 77 }), 78 idToDialer: ds.NewKSet[int64, kiwi.INodeDialer](16, func(dialer kiwi.INodeDialer) int64 { 79 return dialer.NodeId() 80 }), 81 codeToWatchers: make(map[kiwi.TCode]map[int64]struct{}), 82 } 83 ip, err := util.CheckLocalIp(opt.ip) 84 if err != nil { 85 kiwi.Fatal(err) 86 } 87 opt.ip = ip 88 n.worker = worker.NewJobWorker(n.processor) 89 addr := fmt.Sprintf("%s:%d", n.option.ip, n.option.port) 90 switch opt.connType { 91 case Tcp: 92 n.listener = network.NewTcpListener(addr, n.onAddTcpConn) 93 case Udp: 94 n.listener = network.NewUdpListener(addr, n.onAddUdpConn) 95 } 96 97 err = n.listener.Start() 98 if err != nil { 99 panic(err.Error()) 100 } 101 102 n.worker.Start() 103 return n 104 } 105 106 type nodeNet struct { 107 nodeBase 108 option *nodeOption 109 worker *worker.JobWorker 110 svcToDialer *ds.KSet2[kiwi.TSvc, int64, kiwi.INodeDialer] 111 idToDialer *ds.KSet[int64, kiwi.INodeDialer] 112 listener kiwi.IListener 113 codeToWatchers map[kiwi.TCode]map[int64]struct{} //本机方法的远程监听者 114 watcherToCodes map[int64][]kiwi.TCode //远程机监听的方法 115 } 116 117 func (n *nodeNet) Init() *util.Err { 118 return nil 119 } 120 121 func (n *nodeNet) Ip() string { 122 return n.option.ip 123 } 124 125 func (n *nodeNet) Port() int { 126 return n.listener.Port() 127 } 128 129 func (n *nodeNet) Connect(ip string, port int, svc kiwi.TSvc, nodeId int64, ver string, head util.M) { 130 n.worker.Push(nodeConnect, ip, port, svc, nodeId, ver, head) 131 } 132 133 func (n *nodeNet) Disconnect(svc kiwi.TSvc, nodeId int64) { 134 n.worker.Push(nodeDisconnect, svc, nodeId) 135 } 136 137 func (n *nodeNet) onConnected(dialer *nodeDialer) { 138 n.worker.Push(nodeConnected, dialer) 139 } 140 141 func (n *nodeNet) onDisconnected(dialer *nodeDialer, err *util.Err) { 142 n.worker.Push(nodeDisconnected, dialer, err) 143 } 144 145 func (n *nodeNet) pushSelf(pus kiwi.ISndPush) { 146 pkt := NewRcvPusPkt() 147 msg := pus.Msg() 148 if msg != nil { 149 pkt.InitWithMsg(HdPush, pus.Tid(), pus.Head(), pus.Json(), pus.Msg()) 150 } else { 151 err := pkt.InitWithBytes(HdPush, pus.Tid(), pus.Head(), pus.Json(), pus.Payload()) 152 if err != nil { 153 kiwi.Error(err) 154 return 155 } 156 } 157 kiwi.Router().OnPush(pkt) 158 } 159 160 func (n *nodeNet) Push(pus kiwi.ISndPush) { 161 if kiwi.GetNodeMeta().HasService(pus.Svc()) { 162 n.pushSelf(pus) 163 return 164 } 165 n.worker.Push(nodePush, pus) 166 } 167 168 func (n *nodeNet) PushNode(nodeId int64, pus kiwi.ISndPush) { 169 if nodeId == kiwi.GetNodeMeta().NodeId { 170 n.pushSelf(pus) 171 return 172 } 173 n.worker.Push(nodePushNode, nodeId, pus) 174 } 175 176 func (n *nodeNet) requestSelf(req kiwi.ISndRequest) { 177 pkt := NewRcvReqPkt() 178 msg := req.Msg() 179 if msg != nil { 180 pkt.InitWithMsg(HdRequest, req.Tid(), req.Head(), req.Json(), req.Msg()) 181 } else { 182 err := pkt.InitWithBytes(HdRequest, req.Tid(), req.Head(), req.Json(), req.Payload()) 183 if err != nil { 184 kiwi.Error(err) 185 return 186 } 187 } 188 kiwi.Router().OnRequest(pkt) 189 } 190 191 func (n *nodeNet) Request(req kiwi.ISndRequest) { 192 if kiwi.GetNodeMeta().HasService(req.Svc()) { 193 n.requestSelf(req) 194 return 195 } 196 n.worker.Push(nodeRequest, req) 197 } 198 199 func (n *nodeNet) RequestNode(nodeId int64, req kiwi.ISndRequest) { 200 if nodeId == kiwi.GetNodeMeta().NodeId { 201 n.requestSelf(req) 202 return 203 } 204 n.worker.Push(nodeRequestNode, req) 205 } 206 207 func (n *nodeNet) Notify(ntf kiwi.ISndNotice) { 208 n.worker.Push(nodeSendNotify, ntf) 209 } 210 211 func (n *nodeNet) ReceiveWatchNotice(nodeId int64, codes []kiwi.TCode) { 212 n.worker.Push(nodeWatchNotify, nodeId, codes) 213 } 214 215 func (n *nodeNet) SendToNode(nodeId int64, bytes []byte, fnErr util.FnErr) { 216 n.worker.Push(nodeSendNode, nodeId, bytes, fnErr) 217 } 218 219 func (n *nodeNet) onAddTcpConn(conn net.Conn) { 220 addr := conn.RemoteAddr().String() 221 agent := network.NewTcpAgent(addr, n.receive, 222 kiwi.AgentErr(func(err *util.Err) { 223 err.AddParam("addr", addr) 224 kiwi.Error(err) 225 }), 226 kiwi.AgentMode(kiwi.AgentR), 227 kiwi.AgentDeadline(30), 228 ) 229 agent.Start(util.Ctx(), conn) 230 } 231 232 func (n *nodeNet) onAddUdpConn(conn net.Conn) { 233 addr := conn.RemoteAddr().String() 234 agent := network.NewUdpAgent(addr, n.receive, 235 kiwi.AgentErr(func(err *util.Err) { 236 err.AddParam("addr", addr) 237 kiwi.Error(err) 238 }), 239 kiwi.AgentMode(kiwi.AgentR), 240 kiwi.AgentDeadline(30), 241 ) 242 agent.Start(util.Ctx(), conn) 243 } 244 245 func (n *nodeNet) createDialer(name, addr string) kiwi.IDialer { 246 switch n.option.connType { 247 case Tcp: 248 return network.NewTcpDialer(name, addr, n.receive, kiwi.AgentMode(kiwi.AgentW)) 249 case Udp: 250 return network.NewUdpDialer(name, addr, n.receive, kiwi.AgentMode(kiwi.AgentW)) 251 default: 252 kiwi.Fatal2(util.EcParamsErr, util.M{ 253 "conn type": n.option.connType, 254 }) 255 return nil 256 } 257 } 258 259 func (n *nodeNet) processor(job *worker.Job) { 260 switch job.Name { 261 case nodeConnect: 262 ip, port, svc, nodeId, ver, head := util.SplitSlc6[string, int, kiwi.TSvc, int64, string, util.M](job.Data) 263 if n.idToDialer.Has(nodeId) { 264 kiwi.Info("exist service", util.M{ 265 "node id": nodeId, 266 }) 267 return 268 } 269 kiwi.Info("connect service", util.M{ 270 "ip": ip, 271 "port": port, 272 "svc": svc, 273 "node id": nodeId, 274 "ver": ver, 275 "head": head, 276 }) 277 dialer := n.createDialer(fmt.Sprintf("%s_%d", svc, nodeId), fmt.Sprintf("%s:%d", ip, port)) 278 newNodeDialer(dialer, svc, nodeId, ver, head, n.onConnected, n.onDisconnected).connect() 279 case nodeConnected: 280 dialer := util.SplitSlc1[*nodeDialer](job.Data) 281 set, _ := n.svcToDialer.GetOrNew(dialer.svc, func() *ds.Set2Item[kiwi.TSvc, int64, kiwi.INodeDialer] { 282 return ds.NewSet2Item[kiwi.TSvc, int64, kiwi.INodeDialer](dialer.svc, 2, func(dialer kiwi.INodeDialer) int64 { 283 return dialer.NodeId() 284 }) 285 }) 286 old := set.Set(dialer) 287 if old != nil { 288 kiwi.Error2(util.EcExist, util.M{ 289 "node id": dialer.nodeId, 290 }) 291 } 292 _ = n.idToDialer.Set(dialer) 293 kiwi.Info("service connected", util.M{ 294 "svc": dialer.svc, 295 "ver": dialer.ver, 296 "node id": dialer.nodeId, 297 "head": dialer.head, 298 }) 299 //发送消息监听 300 codes, ok := kiwi.Router().GetWatchCodes(dialer.Svc()) 301 if ok { 302 bytes := kiwi.Packer().PackWatchNotify(kiwi.GetNodeMeta().NodeId, codes) 303 dialer.Send(bytes, kiwi.Error) 304 } 305 var head util.M 306 dialer.head.CopyTo(head) 307 kiwi.DispatchEvent(kiwi.Evt_Svc_Connected, &kiwi.EvtSvcConnected{ 308 Svc: dialer.svc, 309 Id: dialer.nodeId, 310 Head: head, 311 }) 312 case nodeDisconnected: 313 dialer, err := util.SplitSlc2[*nodeDialer, *util.Err](job.Data) 314 set, ok := n.svcToDialer.Get(dialer.svc) 315 if !ok { 316 return 317 } 318 nodeId := dialer.nodeId 319 _, ok = set.Del(nodeId) 320 if !ok { 321 return 322 } 323 _, _ = n.idToDialer.Del(nodeId) 324 codes, ok := n.watcherToCodes[nodeId] 325 if ok { 326 for _, code := range codes { 327 m, ok := n.codeToWatchers[code] 328 if ok { 329 delete(m, nodeId) 330 } 331 } 332 } 333 kiwi.Info("dialer disconnected", util.M{ 334 "error": err, 335 "svc": dialer.svc, 336 "node id": dialer.nodeId, 337 "head": dialer.head, 338 }) 339 kiwi.DispatchEvent(kiwi.Evt_Svc_Disonnected, &kiwi.EvtSvcDisconnected{ 340 Svc: dialer.svc, 341 Id: dialer.nodeId, 342 }) 343 case nodeDisconnect: 344 svc, nodeId := util.SplitSlc2[kiwi.TSvc, int64](job.Data) 345 set, ok := n.svcToDialer.Get(svc) 346 if !ok { 347 return 348 } 349 dialer, ok := set.Get(nodeId) 350 if !ok { 351 return 352 } 353 kiwi.Info("disconnect service", util.M{ 354 "service": dialer.Svc(), 355 "node id": dialer.NodeId(), 356 "head": dialer.Head(), 357 }) 358 dialer.Dialer().Agent().Dispose() 359 case nodeSendNotify: 360 ntf := job.Data[0].(kiwi.ISndNotice) 361 tid := ntf.Tid() 362 bytes, err := kiwi.Packer().PackNotify(tid, ntf) 363 if err != nil { 364 kiwi.TE(tid, err) 365 return 366 } 367 m, ok := n.codeToWatchers[ntf.Code()] 368 if !ok { 369 return 370 } 371 for nodeId := range m { 372 dialer, ok := n.idToDialer.Get(nodeId) 373 if !ok { 374 delete(m, nodeId) 375 break 376 } 377 dialer.Send(util.CopyBytes(bytes), nil) 378 } 379 case nodeWatchNotify: 380 nodeId, codes := util.SplitSlc2[int64, []kiwi.TCode](job.Data) 381 _, ok := n.idToDialer.Get(nodeId) 382 if !ok { 383 kiwi.Error2(util.EcNotExist, util.M{ 384 "node id": nodeId, 385 }) 386 return 387 } 388 n.watcherToCodes[nodeId] = codes 389 for _, code := range codes { 390 m, ok := n.codeToWatchers[code] 391 if ok { 392 m[nodeId] = struct{}{} 393 } else { 394 n.codeToWatchers[code] = map[int64]struct{}{ 395 nodeId: {}, 396 } 397 } 398 } 399 case nodePush: 400 pus := job.Data[0].(kiwi.ISndPush) 401 tid := pus.Tid() 402 bytes, err := kiwi.Packer().PackPush(tid, pus) 403 if err != nil { 404 kiwi.TE(tid, err) 405 return 406 } 407 n.sendToSvc(pus.Svc(), bytes, func(err *util.Err) { 408 kiwi.TE(tid, err) 409 }) 410 case nodePushNode: 411 nodeId, pus := util.SplitSlc2[int64, kiwi.ISndPush](job.Data) 412 tid := pus.Tid() 413 bytes, err := kiwi.Packer().PackPush(tid, pus) 414 if err != nil { 415 kiwi.TE(tid, err) 416 return 417 } 418 n.sendToNode(nodeId, bytes, func(err *util.Err) { 419 kiwi.TE(tid, err) 420 }) 421 case nodeRequest: 422 req := job.Data[0].(kiwi.ISndRequest) 423 tid := req.Tid() 424 bytes, err := kiwi.Packer().PackRequest(tid, req) 425 if err != nil { 426 kiwi.TE(tid, err) 427 return 428 } 429 n.sendToSvc(req.Svc(), bytes, func(err *util.Err) { 430 kiwi.TE(tid, err) 431 }) 432 case nodeRequestNode: 433 nodeId, req := util.SplitSlc2[int64, kiwi.ISndRequest](job.Data) 434 tid := req.Tid() 435 bytes, err := kiwi.Packer().PackRequest(tid, req) 436 if err != nil { 437 kiwi.TE(tid, err) 438 return 439 } 440 n.sendToNode(nodeId, bytes, func(err *util.Err) { 441 kiwi.TE(tid, err) 442 }) 443 case nodeSendNode: 444 n.sendToNode(util.SplitSlc3[int64, []byte, util.FnErr](job.Data)) 445 } 446 } 447 448 func (n *nodeNet) sendToSvc(svc kiwi.TSvc, bytes []byte, fnErr util.FnErr) { 449 set, ok := n.svcToDialer.Get(svc) 450 if !ok { 451 fnErr(util.NewErr(util.EcNotExist, util.M{ 452 "svc": svc, 453 })) 454 return 455 } 456 switch set.Count() { 457 case 0: 458 fnErr(util.NewErr(util.EcNotExist, util.M{ 459 "svc": svc, 460 })) 461 case 1: 462 dialer, _ := set.GetWithIdx(0) 463 dialer.Send(bytes, fnErr) 464 default: 465 nodeId, err := n.option.selector(set) 466 if err != nil { 467 fnErr(err) 468 return 469 } 470 dialer, ok := n.idToDialer.Get(nodeId) 471 if !ok { 472 fnErr(util.NewErr(util.EcNotExist, util.M{ 473 "id": nodeId, 474 })) 475 return 476 } 477 dialer.Send(bytes, fnErr) 478 } 479 } 480 481 func (n *nodeNet) sendToNode(nodeId int64, bytes []byte, fnErr util.FnErr) { 482 dialer, ok := n.idToDialer.Get(nodeId) 483 if !ok { 484 fnErr(util.NewErr(util.EcNotExist, util.M{ 485 "id": nodeId, 486 })) 487 return 488 } 489 dialer.Send(bytes, fnErr) 490 } 491 492 const ( 493 nodeConnect = "svc_connect" 494 nodeConnected = "svc_connected" 495 nodeDisconnect = "svc_disconnect" 496 nodeDisconnected = "svc_disconnected" 497 nodeSendNotify = "send_notify" 498 nodeWatchNotify = "listen_notify" 499 nodePush = "push" 500 nodePushNode = "push_node" 501 nodeRequest = "request" 502 nodeRequestNode = "request_node" 503 nodeSendNode = "send_node" 504 )