func (h *DBHandler) Login(head *protocol.PackageHead, jsonBody []byte, tail *protocol.PackageTail) (result []byte) { var req protocol.LoginRequest var rsp protocol.LoginResponse errCode := 0 var err error = nil defer func() { rsp.ErrorCode = proto.Uint32(uint32(errCode)) syslog.Debug(rsp.String()) result, err = proto.Marshal(&rsp) if err != nil { syslog.Debug(err) } }() if err := proto.Unmarshal(jsonBody, &req); err != nil { errCode = errors.Code(errors.CLIENT_ERR_UNKNOW_ERROR) return } phonenum := req.GetUsername() password := req.GetPassword() userInfo, _ := user.GetUserInfoByPhoneNum(phonenum) if userInfo == nil { errCode = errors.Code(errors.CLIENT_ERR_USER_NOT_EXIST) return } if userInfo.Password != password { errCode = errors.Code(errors.CLIENT_ERR_PASSWORD_ERROR) return } us, err := user.GetUserState(userInfo.Uid) if err != nil { syslog.Info("GetUserState failed!!!", err) } us.Uid = userInfo.Uid us.Sid = tail.SID us.ConnIP = tail.IP us.ConnPort = tail.Port //us.SetupId = req.SetupId us.Online = true if err := user.SetUserState(us); err != nil { syslog.Info("SetUserState failed", us) } rsp.UserId = proto.Uint64(userInfo.Uid) tail.UID = userInfo.Uid return }
func (msg *UserMsgItem) SafeMapTimeoutCall(key interface{}) { // 超时未删除则保存到db c := common.MongoCollection(MSG_DB, MSG_USER_MSG_TABLE) if err := c.Insert(msg); err != nil { syslog.Info(err, *msg) } }
func SaveUserMsgToDB(userMsg *UserMsgItem) { // 超时未删除则保存到db c := common.MongoCollection(MSG_DB, MSG_USER_MSG_TABLE) if err := c.Insert(userMsg); err != nil { syslog.Info(err, *userMsg) } }
func (c *Client) Response(msg *protocol.DataPackage) error { head := msg.Head tail := msg.Tail if (head.Command == protocol.CLIENT_CMD_USER_LOGIN || head.Command == protocol.CLIENT_CMD_USER_REGISTER) && tail.UID != 0 { c.Uid = tail.UID c.Stat = CLIENT_STATE_ONLINE } buf := protocol.GetBuffer() defer protocol.PutBuffer(buf) binary.Write(buf, binary.BigEndian, head) binary.Write(buf, binary.BigEndian, msg.BodyData()) // write to Conn c.Conn.SetDeadline(time.Now().Add(NET_WRITE_DATELINE)) if _, err := c.Conn.Write(buf.Bytes()); err != nil { if e, ok := err.(net.Error); ok && e.Timeout() { syslog.Info("write timeouat:", err, *c) return nil } syslog.Warn("write to conn fail :", err.Error(), msg.Tail) return errors.As(err) } else { syslog.Debug2("write to conn success:", head, string(msg.BodyData()), msg.Tail) } return nil }
func (h *Handler) HandleMessage(message *nsq.Message) error { dataPackage := common.GetDataPackage() defer common.PutDataPackage(dataPackage) if err := dataPackage.Unpackage(message.Body); err != nil { syslog.Warn(err) return nil } head := &dataPackage.Head jsonStr := dataPackage.BodyData() tail := &dataPackage.Tail switch head.Command { case common.XXX_CMD_SEND_USER_MSG: default: syslog.Warn("Invalid Cmd :", head.Command, *tail) } // get user state us, err := user.GetUserState(tail.UID) if err != nil { syslog.Info("GetUserState failed!!!", tail) return nil } // not online if us.Online == false { syslog.Debug("client not online!!! uid:", tail.UID) return nil } tail.IP = us.ConnIP tail.Port = us.ConnPort tail.SID = us.Sid tail.UID = us.Uid respBuf := common.GetBuffer() defer common.PutBuffer(respBuf) if err := common.Package(respBuf, head, jsonStr, tail); err != nil { syslog.Info(err) return nil } topic := fmt.Sprintf("conn_%s_%d", util.IPToStr(tail.IP), tail.Port) common.NsqPublish(topic, respBuf.Bytes()) return nil }
func (h *Handler) HandleMessage(message *nsq.Message) error { dataPackage := common.GetDataPackage() defer common.PutDataPackage(dataPackage) if err := dataPackage.Unpackage(message.Body); err != nil { syslog.Warn(err) return nil } head := &dataPackage.Head jsonStr := dataPackage.BodyData() tail := &dataPackage.Tail var err error = nil resp := []byte("") switch head.Command { case common.XXX_CMD_SEND_USER_MSG: resp, err = h.SendMsg(head, jsonStr, tail) case common.XXX_CMD_RECV_USER_MSG: //resp, err = h.ReceivedUserMsg(head, jsonStr, &tail) common.NsqPublish(common.MSG_STORE_TOPIC, message.Body) default: syslog.Info("invalid cmd:", head.Command, *tail) return nil } if err != nil { syslog.Warn("msg_server msg handle failed:", err, head, tail) head.ErrorCode = uint32(errors.Code(err)) resp = []byte("") } head.PkgLen = uint16(common.DATA_PACKAGE_HEAD_SIZE + len(resp)) respBuf := common.GetBuffer() defer common.PutBuffer(respBuf) if err := common.Package(respBuf, head, resp, tail); err != nil { syslog.Info(err) return nil } topic := fmt.Sprintf("conn_%s_%d", util.IPToStr(tail.IP), tail.Port) common.NsqPublish(topic, respBuf.Bytes()) return nil }
func (c *Client) Stop() { if 0 < atomic.LoadInt32(&c.MsgCount) { time.AfterFunc(time.Second*30, c.Stop) return } syslog.Debug("client ", c.Uid, "Sid ", c.Sid, " disconnect!!", c.Conn.RemoteAddr()) c.Conn.Close() us, err := user.GetUserState(c.Uid) if err != nil { syslog.Info("GetUserState failed!!!", err) } if us.Uid == c.Uid && us.Sid == c.Sid { if err := user.SetUserState(&user.UserState{Uid: c.Uid}); err != nil { syslog.Info("SetUserState failed!!!", err) } } c.Stat = CLIENT_STATE_OFFLINE c.Service.RWMutex.Lock() delete(c.Service.ClientMap, c.Sid) c.Service.RWMutex.Unlock() atomic.AddInt32(&c.Service.ClientCount, -1) PutClient(c) }
func (this *Service) P2pService(sock *net.UDPConn) { this.WaitGroup.AddOne() defer this.WaitGroup.Done() exitNotify := this.WaitGroup.ExitNotify() var buf [2048]byte for { select { case <-exitNotify: return default: } sock.SetDeadline(time.Now().Add(NET_READ_MAX_DATELINE)) n, addr, err := sock.ReadFromUDP(buf[:]) if err != nil { syslog.Info(err) continue } if n < 4 { syslog.Info("udp data package too small") continue } sid := binary.BigEndian.Uint32(buf[:4]) this.RWMutex.RLock() client, ok := this.ClientMap[sid] this.RWMutex.RUnlock() if ok == false { syslog.Debug("client not exist!!! sid:", sid) continue } client.IP = util.IPToInt(addr.String()) client.Port = uint32(addr.Port) if _, err := sock.WriteToUDP([]byte(addr.String()), addr); err != nil { syslog.Info("udp send data failed!!!", err) continue } } }
func StartServer() { iniConf := common.Config() ip := iniConf.DefaultString("tcp_ip", "10.0.2.15") port := iniConf.DefaultString("tcp_port", "8888") g_IP = util.IPToInt(ip) g_Port = uint32(util.Atoi(port)) listener, err := common.TCPServer(ip + ":" + port) if err != nil { panic(err) } /* udp_addr1 := iniConf.DefaultString("udp_address1", "127.0.0.1:9100") udp_addr2 := iniConf.DefaultString("udp_address2", "127.0.0.1:9101") udpSocket1, err := common.UDPServer(udp_addr1) if err != nil { panic(err) } udpSocket2, err := common.UDPServer(udp_addr2) if err != nil { panic(err) } */ service := &Service{ Listener: listener, ClientCh: make(chan *Client, 1000), WaitGroup: sync_.NewWaitGroup(), ClientMap: make(map[uint32]*Client), RWMutex: &sync.RWMutex{}, } for i := 0; i < CLIENT_GROUP_NUM; i++ { NewClientGroup(service) } go service.Serve() //go service.P2pService(udpSocket1) //go service.P2pService(udpSocket2) topic := fmt.Sprintf("conn_%v_%v", ip, port) if _, err := common.NsqConsumerGO(topic, "conn-channel", 3, service); err != nil { panic(err) } // Handle SIGINT and SIGTERM. ch := make(chan os.Signal) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL) syslog.Info("recv signal and exit:", <-ch) service.Stop() return }
func QiniuDeleteFiles(keys []string) error { if len(keys) == 0 { return nil } entryPathes := []rs.EntryPath{} for _, key := range keys { entryPathes = append(entryPathes, rs.EntryPath{Bucket: g_bucket_name, Key: key}) } _, err := g_file_mgr.rsClient.BatchDelete(nil, entryPathes) if err != nil { syslog.Info(err, keys) } deleteFile(keys) return nil }
func (c *Client) Request() bool { var reqBuf [2048]byte curTime := time.Now().Unix() c.Conn.SetDeadline(time.Now().Add(NET_READ_DATELINE)) if _, err := io.ReadFull(c.Conn, reqBuf[:2]); err != nil { if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { // 太长时间没有交互退出 if c.Stat == CLIENT_STATE_INIT && c.LastTime+CONNECT_NO_LOGIN_TIMEOUT < curTime { syslog.Info(c.Uid, c.Sid, "no login timeout 30 s, lastTime:", c.LastTime, " nowTime:", curTime) return false } else if c.LastTime+CONNECT_NO_REQUEST_TIMEOUT < curTime { syslog.Info(c.Uid, c.Sid, "timeout 180 s, lastTime:", c.LastTime, " nowTime:", curTime) return false } return true } syslog.Info(c.Uid, c.Sid, "recv error:", err.Error()) return false } else { headLen := binary.BigEndian.Uint16(reqBuf[0:2]) if headLen > protocol.DATA_PACKAGE_MAX_SIZE { syslog.Info(c.Uid, c.Sid, "head len :", headLen, " too large", reqBuf[0], reqBuf[1]) return true } else if headLen < protocol.DATA_PACKAGE_HEAD_SIZE { syslog.Info(c.Uid, c.Sid, "head len :", headLen, " too small", reqBuf[0], reqBuf[1]) return true } c.Conn.SetDeadline(time.Now().Add(NET_READ_MAX_DATELINE)) if _, err := io.ReadFull(c.Conn, reqBuf[2:headLen]); err != nil { syslog.Info(c.Uid, c.Sid, "recv error:", err) return false } dataPackage := protocol.GetDataPackage() defer protocol.PutDataPackage(dataPackage) if err := dataPackage.Unpackage(reqBuf[:headLen]); err != nil { syslog.Info(c.Uid, c.Sid, "DecPkgBody failed :", err) return false } head := dataPackage.Head syslog.Debug("client requst:", head) if head.Command != protocol.CLIENT_CMD_HEARTBEAT && head.Command != protocol.CLIENT_CMD_USER_LOGIN && head.Command != protocol.CLIENT_CMD_USER_REGISTER && c.Stat != CLIENT_STATE_ONLINE { syslog.Info("no login no operate!!!", head) return false } else { c.LastTime = time.Now().Unix() dataPackage.Tail.IP = g_IP dataPackage.Tail.Port = g_Port dataPackage.Tail.SID = c.Sid dataPackage.Tail.UID = c.Uid dataPackage.Data = c if head.Command != protocol.CLIENT_CMD_HEARTBEAT { //派发消息到其它服务器处理 err = c.Produce(dataPackage) } else { //回复心跳 err = c.Response(dataPackage) } if err != nil { syslog.Info(err) return false } } } return true }