Exemple #1
0
func (self *Manager) handleMsgServerClient(msc *link.Session) {
	msc.ReadLoop(func(msg link.InBuffer) {
		glog.Info("msg_server", msc.Conn().RemoteAddr().String(), "say:", string(msg.Get()))

		self.parseProtocol(msg.Get(), msc)
	})
}
//其他客户端连接TransferServer处理
func connectTransferServer(session *link.Session, protoMsg systemProto.ProtoMsg) {
	rev_msg := protoMsg.Body.(*systemProto.System_ConnectTransferServerC2S)

	serverName := rev_msg.GetServerName()
	INFO(serverName + " Connect TransferServer")

	useServerName := strings.Split(serverName, "[")[0]
	sessions, exists := servers[useServerName]
	if !exists {
		sessions = make([]*link.Session, 0, 10)
	}
	sessions = append(sessions, session)
	servers[useServerName] = sessions

	//GameServer可以有多个
	if useServerName == "GameServer" {
		addr := strings.Split(session.Conn().RemoteAddr().String(), ":")
		addrIp := addr[0]
		addrPort, _ := strconv.Atoi(addr[1])
		gameConsistent.Add(hashs.NewNode(len(sessions), addrIp, addrPort, serverName, 1))
	}

	send_msg := systemProto.MarshalProtoMsg(&systemProto.System_ConnectTransferServerS2C{})
	systemProto.Send(send_msg, session)

	startDealReceiveMsgC2S(session)
}
func newFrontLink(session *link.Session, linkID uint64) *frontendLink {
	flink := &frontendLink{
		session:     session,
		linkId:      linkID,
		clients:     make(map[uint64]*link.Session),
		clientWaits: make(map[uint64]*link.Session),
	}

	session.AddCloseCallback(flink, func() {
		flink.Close()
	})

	go func() {
		var msg = gatewayMsg{}
		for {
			if err := session.Receive(&msg); err != nil {
				break
			}
			switch msg.Command {
			case CMD_MSG:
				flink.dispathMsg(msg.ClientId, msg.Data)
			case CMD_BRD:
				flink.broadcast(msg.ClientIds, msg.Data)
			case CMD_NEW_2:
				flink.newClient(msg.ClientId, msg.ClientIds[0])
			case CMD_DEL:
				flink.delClient(msg.ClientId, false)
			}
		}
		flink.Close()
	}()

	return flink
}
Exemple #4
0
//登录
func (this UserModule) Login(userName string, session *link.Session) {
	onlineUser := module.Cache.GetOnlineUserByUserName(userName)
	if onlineUser != nil {
		if onlineUser.Session.Id() != session.Id() {
			//当前在线,但是连接不同,其他客户端连接,需通知当前客户端下线
			module.SendOtherLogin(onlineUser.Session)
			//替换Session
			module.Cache.RemoveOnlineUser(onlineUser.Session.Id())
			//登录成功处理
			success := loginSuccess(session, onlineUser.UserName, onlineUser.UserID)
			if success {
				module.SendLoginResult(onlineUser.UserID, session)
			} else {
				module.SendLoginResult(0, session)
			}
		}
	} else {
		cacheDbUser := redisProxy.GetDBUserByUserName(userName)
		if cacheDbUser != nil {
			this.UserLoginHandle(session, cacheDbUser.Name, cacheDbUser.ID)
		} else {
			dbProxy.UserLogin(session.Id(), userName)
		}
	}
}
Exemple #5
0
func (self *Router) handleMsgServerClient(msc *link.Session) {
	msc.ReadLoop(func(msg link.InBuffer) {
		glog.Info("msg_server", msc.Conn().RemoteAddr().String(), " say: ", string(msg.Get()))
		var c protocol.CmdInternal
		pp := NewProtoProc(self)
		err := json.Unmarshal(msg.Get(), &c)
		if err != nil {
			glog.Error("error:", err)
		}
		switch c.GetCmdName() {
		case protocol.SEND_MESSAGE_P2P_CMD:
			err := pp.procSendMsgP2P(c, msc)
			if err != nil {
				glog.Warning(err.Error())
			}
		case protocol.CREATE_TOPIC_CMD:
			err := pp.procCreateTopic(c, msc)
			if err != nil {
				glog.Warning(err.Error())
			}
		case protocol.JOIN_TOPIC_CMD:
			err := pp.procJoinTopic(c, msc)
			if err != nil {
				glog.Warning(err.Error())
			}
		case protocol.SEND_MESSAGE_TOPIC_CMD:
			err := pp.procSendMsgTopic(c, msc)
			if err != nil {
				glog.Warning(err.Error())
			}

		}
	})
}
//LoginServer用户上线
func SetClientSessionOnline(userSession *link.Session) {
	//发送用户上线消息到serverName
	protoMsg := &systemProto.System_ClientSessionOnlineC2S{
		SessionID: protos.Uint64(userSession.Id()),
		Network:   protos.String(userSession.Conn().RemoteAddr().Network()),
		Addr:      protos.String(userSession.Conn().RemoteAddr().String()),
	}
	send_msg := protos.MarshalProtoMsg(protoMsg)
	sendSystemMsg2("LoginServer", 0, send_msg)
}
Exemple #7
0
func sessionReceive(session *link.Session, d dispatch.DispatchInterface) {
	for {
		var msg []byte
		if err := session.Receive(&msg); err != nil {
			break
		}

		d.Process(session, msg)
	}
}
Exemple #8
0
func handleSession(ms *MsgServer, session *link.Session) {
	session.ReadLoop(func(msg link.InBuffer) {
		glog.Info(string(msg.Get()))

		err := ms.parseProtocol(msg.Get(), session)
		if err != nil {
			glog.Error(err.Error())
		}
	})
}
Exemple #9
0
func AddSession(session *link.Session) {
	sessionMutex.Lock()
	defer sessionMutex.Unlock()

	sessionNum += 1
	sessions[session.Id()] = session
	session.AddCloseCallback(session, func() {
		RemoveSession(session)
		sessionNum -= 1
	})
}
//通知GameServer用户登录成功
func SetClientLoginSuccess(userName string, userID uint64, session *link.Session) {
	send_msg := protos.MarshalProtoMsg(&systemProto.System_ClientLoginSuccessC2S{
		UserID:       protos.Uint64(userID),
		UserName:     protos.String(userName),
		SessionID:    protos.Uint64(session.Id()),
		GameServerID: protos.Uint32(0),
		Network:      protos.String(session.Conn().RemoteAddr().Network()),
		Addr:         protos.String(session.Conn().RemoteAddr().String()),
	})
	sendSystemMsgToServer(send_msg)
}
Exemple #11
0
func BytesTest(t *testing.T, session *link.Session) {
	for i := 0; i < 2000; i++ {
		msg1 := RandBytes(512)
		err := session.Send(msg1)
		unitest.NotError(t, err)

		var msg2 []byte
		err = session.Receive(&msg2)
		unitest.NotError(t, err)
		unitest.Pass(t, bytes.Equal(msg1, msg2))
	}
}
Exemple #12
0
func ObjectTest(t *testing.T, session *link.Session) {
	for i := 0; i < 2000; i++ {
		msg1 := RandObject()
		err := session.Send(&msg1)
		unitest.NotError(t, err)

		var msg2 TestObject
		err = session.Receive(&msg2)
		unitest.NotError(t, err)
		unitest.Pass(t, msg1 == msg2)
	}
}
Exemple #13
0
func StringTest(t *testing.T, session *link.Session) {
	for i := 0; i < 2000; i++ {
		msg1 := string(RandBytes(512))
		err := session.Send(msg1)
		unitest.NotError(t, err)

		var msg2 string
		err = session.Receive(&msg2)
		unitest.NotError(t, err)
		unitest.Pass(t, msg1 == msg2)
	}
}
func (flink *frontendLink) AddClient(session *link.Session) {
	flink.clientMutex.Lock()
	defer flink.clientMutex.Unlock()

	flink.clientWaitId += 1
	flink.clientWaits[flink.clientWaitId] = session

	addr := session.Conn().RemoteAddr()
	flink.session.Send(&gatewayMsg{
		Command: CMD_NEW_1, ClientId: flink.clientWaitId,
		Data: []byte(addr.Network() + "," + addr.String()),
	})
}
Exemple #15
0
//登录成功后处理
func (this UserModule) dealLoginSuccess(session *link.Session, userName string, userID uint64) {
	//通知GameServer登录成功
	transferProxy.SetClientLoginSuccess(userName, userID, session)
	//发送登录成功消息
	gameProxy.SendLoginResult(session, userID)
	//用户下线时处理
	session.AddCloseCallback(session, func() {
		//记录用户下线Log
		logProxy.UserOffLine(userID)
	})
	//记录用户登录Log
	logProxy.UserLogin(userID)
}
Exemple #16
0
//用户登录成功处理
func (this UserModule) LoginSuccess(session *link.Session, userName string, userID uint64, gameServerID uint32) bool {
	cacheSuccess := module.Cache.AddOnlineUser(userName, userID, session, gameServerID)
	if cacheSuccess {
		session.AddCloseCallback(session, func() {
			module.Cache.RemoveOnlineUser(session.Id())
			DEBUG("用户下线:当前在线人数", module.Cache.GetOnlineUsersNum())
		})
		DEBUG("用户上线:当前在线人数", module.Cache.GetOnlineUsersNum())
		return true
	} else {
		ERR("what????", userName)
		return false
	}
}
Exemple #17
0
func newBackendLink(id uint64, listener *BackendListener, session *link.Session) *backendLink {
	session.EnableAsyncSend(10000)
	this := &backendLink{
		id:       id,
		listener: listener,
		session:  session,
		conns:    make(map[uint64]*BackendConn),
	}
	session.AddCloseCallback(this, func() {
		this.Close(false)
	})
	go this.loop()
	return this
}
//发送消息到TransferServer, 网关调用
func SendToGameServer(userSession *link.Session, msg []byte) {
	send_msg := make([]byte, 8+len(msg))
	copy(send_msg[:2], msg[:2])
	binary.PutUint64LE(send_msg[2:10], userSession.Id())
	copy(send_msg[10:], msg[2:])

	//C2S消息,发送到GameServer或者LoginServer
	msgID := binary.GetUint16LE(send_msg[:2])
	if gameProto.IsValidLoginID(msgID) {
		sendGameMsg("LoginServer", send_msg)
	} else {
		sendGameMsg("GameServer", send_msg)
	}
}
//其他客户端连接LogServer处理
func connectLogServer(session *link.Session, protoMsg protos.ProtoMsg) {
	rev_msg := protoMsg.Body.(*systemProto.System_ConnectLogServerC2S)

	serverName := rev_msg.GetServerName()
	servers[serverName] = session

	session.AddCloseCallback(session, func() {
		delete(servers, serverName)
		ERR(serverName + " Disconnect At " + global.ServerName)
	})

	send_msg := protos.MarshalProtoMsg(&systemProto.System_ConnectLogServerS2C{})
	protos.Send(session, send_msg)
}
Exemple #20
0
///============================
///消费者 获取图片
func getFile(session *link.Session, req map[string]string) error {
	seq := req["seq"]

	//死等
	vf := QueueInstance.DeChan()
	if vf == nil {
		ULogger.Error("getfile time out,sessioninfo is %s", session.State.(*User).Id)
		ret := map[string]string{
			"action": "res_getfile",
			"seq":    seq,
		}
		by, _ := json.Marshal(ret)
		session.Send(link.Bytes(by))
		ULogger.Info("send to client", session.Conn().RemoteAddr().String(), "say:", string(by))
		return nil
	}
	vf.C = session
	vf.CInfo = session.State.(*User).Id
	vf.Status = 2
	vf.CGetUnix = time.Now().Unix()
	ret := map[string]string{
		"action": "res_getfile",
		"seq":    seq,
		"id":     vf.Id,
		"file":   vf.File,
	}
	by, _ := json.Marshal(ret)
	VFMapInstance.Update("c_getfile", vf)
	session.Send(link.Bytes(by))
	ULogger.Info("send to client", session.Conn().RemoteAddr().String(), "say:", string(by))
	return nil
}
Exemple #21
0
func SendGetUserInfoResult(errorCode int32, u *UserModel, session *link.Session) {
	if errorCode != 0 {
		SendErrorMsg(errorCode, session)
	} else {
		send_msg := MarshalProtoMsg(&GetUserInfoS2C{
			UserInfo: &Person{
				ID:        protos.Uint64(u.DBUser.ID),
				Name:      protos.String(u.DBUser.Name),
				Money:     protos.Int32(u.DBUser.Money),
				SessionID: protos.Uint64(session.Id()),
			},
		})
		Send(send_msg, session)
	}
}
Exemple #22
0
///======================================
///生产者 ,产生图验图片
func putFile(session *link.Session, req map[string]string) error {
	file := req["file"]
	seq := req["seq"]
	fileid := GetMd5String(file)
	vf := &VerifyObj{Id: getId(), P: session, C: nil, FileId: fileid, File: file, Status: 1, Result: "0", Seq: seq, PPutUnix: time.Now().Unix()}
	QueueInstance.Enqueue(vf)
	VFMapInstance.Put(vf)
	ULogger.Infof("putfile 进队列 %v\n", vf)
	//记录p端的操作
	if session.State == nil {
		userId := session.Conn().RemoteAddr().String()
		user := &User{UserType: "P", Id: userId, WorkTime: time.Now().Format("2006-01-02 15:04:05")}
		session.State = user
		Exec(`insert into user_activities(user_id,active_time,active_type,user_type,other_info) values(?,now(),'begin','production',?)`, userId, userId)
	}
	return nil
}
Exemple #23
0
//获取用户详细信息
func (this UserModule) GetUserInfo(userID uint64, session *link.Session) {
	onlineUser := module.Cache.GetOnlineUserByUserID(userID)
	if onlineUser != nil {
		dbUser := redisProxy.GetDBUser(userID)
		if dbUser != nil {
			userModel := NewUserModel(dbUser)
			module.SendGetUserInfoResult(0, userModel, session)

			//更新用户最后上线时间,更新内存和数据库
			nowTime := time.Now().Unix()
			redisProxy.UpdateUserLastLoginTime(userID, nowTime)
			dbProxy.UpdateUserLastLoginTime(session.Id(), userID, nowTime)

		} else {
			module.SendGetUserInfoResult(gameProto.User_Not_Exists, nil, session)
		}
	} else {
		module.SendGetUserInfoResult(gameProto.User_Login_Fail, nil, session)
	}
}
//开始处理游戏逻辑消息
func startDealReceiveMsgC2S(session *link.Session) {
	revMsgChan := make(chan *packet.RAW, 2048)
	go func() {
		for {
			data, ok := <-revMsgChan
			if !ok {
				return
			}
			dealReceiveMsgC2S(session, *data)
		}
	}()

	for {
		var msg packet.RAW
		if err := session.Receive(&msg); err != nil {
			break
		}
		revMsgChan <- &msg
	}
}
Exemple #25
0
//登录
func (this UserModule) Login(userName string, session *link.Session) {
	onlineUser := module.Cache.GetOnlineUserByUserName(userName)
	if onlineUser != nil {
		if onlineUser.Session.Id() != session.Id() {
			//当前在线,但是连接不同,其他客户端连接,需通知当前客户端下线
			gameProxy.SendOtherLogin(onlineUser.Session)
			//替换Session
			module.Cache.RemoveOnlineUser(onlineUser.Session.Id())
			//登录成功处理
			success := this.LoginSuccess(session, onlineUser.UserName, onlineUser.UserID, 0)
			if success {
				//登录成功后处理
				this.dealLoginSuccess(session, userName, onlineUser.UserID)
			} else {
				gameProxy.SendLoginResult(session, 0)
			}
		}
	} else {
		dbProxy.UserLogin(session.Id(), userName)
	}
}
Exemple #26
0
//添加在线用户缓存
func (this *CacheModule) AddOnlineUser(userName string, userID uint64, session *link.Session) bool {
	this.onlineUsersMutex.Lock()
	defer this.onlineUsersMutex.Unlock()

	//同一账号只能对应一个Session
	//同一SessionID只能登陆一个账号
	_, exists1 := this.onlineUsers[userName]
	_, exists2 := this.onlineUsersSession[session.Id()]
	if !exists1 && !exists2 {
		model := &OnlineUserModel{
			Session:  session,
			UserID:   userID,
			UserName: userName,
		}
		this.onlineUsers[userName] = model
		this.onlineUsersID[userID] = userName
		this.onlineUsersSession[session.Id()] = userName
		this.onlineUsersNum += 1
		return true
	} else {
		return false
	}
}
//其他客户端连接TransferServer处理
func connectTransferServer(session *link.Session, protoMsg protos.ProtoMsg) {
	rev_msg := protoMsg.Body.(*systemProto.System_ConnectTransferServerC2S)

	serverName := rev_msg.GetServerName()
	serverID := rev_msg.GetServerID()

	useServerName := strings.Split(serverName, "[")[0]
	serverList, exists := servers[useServerName]
	if !exists {
		serverList = make([]Server, 0, 10)
	}
	server := Server{
		session:     session,
		serverID:    serverID,
		serverIndex: len(serverList),
	}
	serverList = append(serverList, server)
	servers[useServerName] = serverList

	//服务器断开连接处理
	session.AddCloseCallback(session, func() {
		serverList = append(serverList[:server.serverIndex], serverList[server.serverIndex+1:]...)
		servers[useServerName] = serverList
		ERR(serverName + " Disconnect At " + global.ServerName)
	})

	//GameServer可以有多个
	if useServerName == "GameServer" {
		addr := strings.Split(session.Conn().RemoteAddr().String(), ":")
		addrIp := addr[0]
		addrPort, _ := strconv.Atoi(addr[1])
		gameNode := hashs.NewNode(server.serverIndex, addrIp, addrPort, serverName, 1)
		gameConsistent.Add(gameNode)

		//GameServer断开连接处理
		session.AddCloseCallback(session, func() {
			//移除此Node
			gameConsistent.Remove(gameNode)
			//将此Node的所有用户断开连接
			for clientSessionID, gameNodeIndex := range gameUserSessions {
				if server.serverIndex == gameNodeIndex {
					clientSession := global.GetSession(clientSessionID)
					if clientSession != nil {
						clientSession.Close()
					}
				}
			}
		})
	}

	//发送连接成功消息
	send_msg := protos.MarshalProtoMsg(&systemProto.System_ConnectTransferServerS2C{})
	protos.Send(session, send_msg)
}
Exemple #28
0
func loginSuccess(session *link.Session, userName string, userID uint64) bool {
	cacheSuccess := module.Cache.AddOnlineUser(userName, userID, session)
	if cacheSuccess {
		session.AddCloseCallback(session, func() {
			module.Cache.RemoveOnlineUser(session.Id())
			DEBUG("下线:在线人数", module.Cache.GetOnlineUsersNum())
		})
		DEBUG("上线:在线人数", module.Cache.GetOnlineUsersNum())

		//通知游戏服务器登录成功
		transferProxy.SendClientLoginSuccess(userName, userID, session.Id())

		return true
	}

	return false
}
Exemple #29
0
//发送消息
func Send(msgBody []byte, session *link.Session) {
	session.Send(packet.RAW(msgBody))
}
Exemple #30
0
func Process(session *link.Session, req map[string]string) error {
	command, ok := req["action"]
	if !ok {
		ULogger.Error("client", session.Conn().RemoteAddr().String(), "bad request ,not found action")
		session.Close()
		return nil

	}
	if (command == "getfile" || command == "answer") && session.State == nil {
		ULogger.Error("client", session.Conn().RemoteAddr().String(), "c must login frist")
		session.Close()
		return nil
	}

	switch command {
	//p
	case "putfile":
		return putFile(session, req)
	case "reportanswer":
		return reportAnswer(session, req)
	//c
	case "getfile":
		return getFile(session, req)
	case "cstart":
		return cStart(session, req)
	case "answer":
		return answer(session, req)
	default:
		ULogger.Error("client", session.Conn().RemoteAddr().String(), "not support command")
		session.Close()
		//ULogger.Info("sssss")
	}
	return nil
}