server.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package main
  2. import (
  3. "git.wanbits.io/joe/franklin/comp"
  4. pb "git.wanbits.io/joe/franklin/protos"
  5. "git.wanbits.io/joe/kettle/log"
  6. "git.wanbits.io/joe/kettle/utl"
  7. "git.wanbits.io/joe/nnet"
  8. "github.com/golang/protobuf/proto"
  9. "go.uber.org/zap"
  10. "time"
  11. )
  12. // C/S packet
  13. type CSPacket struct {
  14. *pb.Request
  15. }
  16. func (self *CSPacket) ShouldClose() (bool, int32) {
  17. return false, 0
  18. }
  19. type SCPacket struct {
  20. resp *pb.Response
  21. closing int32
  22. reason int32
  23. }
  24. func NewSCPacket(resp *pb.Response, params ...int32) *SCPacket {
  25. p := &SCPacket{
  26. resp: resp,
  27. }
  28. if len(params) > 0 {
  29. p.closing = params[0]
  30. }
  31. if len(params) > 1 {
  32. p.reason = params[1]
  33. }
  34. return p
  35. }
  36. func (self *SCPacket) ShouldClose() (bool, int32) {
  37. close_session := false
  38. if self.closing > 0 {
  39. close_session = true
  40. }
  41. return close_session, self.reason
  42. }
  43. // protocol && callback
  44. type CSProtocol struct {
  45. }
  46. func (self *CSProtocol) ReadPacket(conn nnet.IConn) (nnet.IPacket, error) {
  47. buf := comp.GBufPool.Get()
  48. defer comp.GBufPool.Put(buf)
  49. n, err := conn.Read(buf)
  50. if err != nil {
  51. return nil, err
  52. }
  53. var req *pb.Request
  54. err = proto.Unmarshal(buf[:n], req)
  55. if err != nil {
  56. return nil, err
  57. }
  58. p := &CSPacket{
  59. req,
  60. }
  61. return p, nil
  62. }
  63. func (self *CSProtocol) Serialize(packet nnet.IPacket) ([]byte, error) {
  64. p, ok := packet.(*SCPacket)
  65. if !ok {
  66. return nil, utl.ErrInterfaceTransform
  67. }
  68. return proto.Marshal(p.resp)
  69. }
  70. func (self *CSProtocol) OnClosed(ses nnet.ISession, reason int32) {
  71. log.Debug("lost connection", zap.String("remote", ses.GetRawConn().RemoteAddr().String()),
  72. zap.Uint64("id", ses.Id()))
  73. on_C_Logout(ses, nil)
  74. }
  75. func (self *CSProtocol) OnConnected(ses nnet.ISession) (bool, int32) {
  76. log.Debug("new client", zap.String("remote", ses.GetRawConn().RemoteAddr().String()))
  77. return true, 0
  78. }
  79. func (self *CSProtocol) OnMessage(ses nnet.ISession, pkt nnet.IPacket) bool {
  80. p, ok := pkt.(*CSPacket)
  81. if !ok {
  82. return false
  83. }
  84. dispatch(ses, p)
  85. return true
  86. }
  87. // server-side dont handle heartbeat.
  88. func (self *CSProtocol) OnHeartbeat(ses nnet.ISession) bool {
  89. return true
  90. }
  91. // @ses: session
  92. // @st: Response 内部结构的 struct
  93. // @params: [0] 发送后是否关闭 [1] 关闭原因
  94. func SendToClient(ses nnet.ISession, userId uint64, ec pb.ErrCode, st proto.Message, params ...int32) {
  95. // 不做 guid 合法性检查,而直接发出消息
  96. bst, err := proto.Marshal(st)
  97. if nil != err {
  98. log.Error("proto.Marshal", zap.Error(err))
  99. return
  100. }
  101. name := comp.GetMsgName(st)
  102. id := comp.GetMsgId(name)
  103. res := &pb.Response{
  104. MsgId: id,
  105. UserId: userId,
  106. MsgName: name,
  107. Ec: int32(ec),
  108. Res: bst,
  109. }
  110. err = ses.AWrite(NewSCPacket(res, params...), time.Second)
  111. if nil != err {
  112. log.Error("proto.AWrite", zap.Error(err))
  113. }
  114. }
  115. func ForwardClient(pkt *SCPacket) {
  116. ses, err := g_server.GetSession(pkt.resp.UserId)
  117. if err != nil {
  118. log.Error("no userId", zap.Uint64("userId", pkt.resp.UserId))
  119. return
  120. }
  121. err = ses.AWrite(pkt, time.Second)
  122. if err != nil {
  123. log.Error("forward to client", zap.Error(err))
  124. }
  125. }
  126. // 关闭某个用户连接
  127. func KillUserSession(ses nnet.ISession, userId uint64, reason pb.NetCloseReason) {
  128. cmd_offline := &pb.S_Offline{}
  129. cmd_offline.Reason = int32(reason)
  130. SendToClient(ses, userId, pb.ErrCode_OK, cmd_offline, 1, int32(reason))
  131. }