Exemplo n.º 1
0
//------------------------------------------------ 登陆后的数据加载
func LoginProc(sess *Session) bool {
	if sess.User == nil {
		return false
	}

	// 载入建筑表
	if !data_tbl.Get(estates.COLLECTION, sess.User.Id, &sess.Estates) {
		// 创建默认的建筑表
		e := &estates.Manager{}
		e.UserId = sess.User.Id
		sess.Estates = e
	} else {
		// 创建Grid
		sess.Grid = CreateGrid(sess.Estates)
	}

	if !data_tbl.Get(samples.COLLECTION, sess.User.Id, &sess.LatencySamples) {
		s := &samples.Samples{}
		s.UserId = sess.User.Id
		s.Init()
		sess.LatencySamples = s
	}

	//
	if sess.User.CountryCode == "" {
		sess.User.CountryCode = geoip.Query(sess.IP)
	}

	if sess.User.CreatedAt == 0 {
		sess.User.CreatedAt = time.Now().Unix()
	}

	// 开始计算Flush时间
	sess.LastFlushTime = time.Now().Unix()

	// 注册为在线
	gsdb.RegisterOnline(sess, sess.User.Id)

	// 最后, 载入离线消息,并push到MQ, 这里小心MQ的buffer长度,
	// 不能直接调用,有可能消息超过MQ被永远阻塞
	go LoadIPCObjects(sess.User.Id, sess.MQ)

	// 标记在线
	//sess.LoggedIn = true
	return true
}
Exemplo n.º 2
0
//------------------------------------------------ 登陆后的数据加载
func LoginProc(sess *Session) bool {
	if sess.User == nil {
		return false
	}

	// TODO: init data structure for session, such as builds

	// set countrycode
	if sess.User.CountryCode == "" {
		sess.User.CountryCode = geoip.Query(sess.IP)
	}

	// register as online
	gsdb.RegisterOnline(sess, sess.User.Id)

	// load messages
	go LoadIPCObjects(sess.User.Id, sess.MQ)

	return true
}
Exemplo n.º 3
0
//----------------------------------------------- cleanup work after disconnection
func close_work(sess *Session) {
	defer PrintPanicStack()
	if sess.Flag&SESS_LOGGED_IN == 0 {
		return
	}

	// must flush user data
	_flush(sess)

	// notify hub
	hub_client.Logout(sess.User.Id)

	// unregister online at this server
	gsdb.UnregisterOnline(sess.User.Id)

	// close MQ, and save the queue to db
	close(sess.MQ)
	for ipcobject := range sess.MQ {
		forward_tbl.Push(&ipcobject)
		NOTICE("re-pushed ipcobject back to db, userid:", sess.User.Id)
	}

	NOTICE(sess.User.Name, "disconnected from", sess.IP, "country:", geoip.Query(sess.IP))
}
Exemplo n.º 4
0
//----------------------------------------------- start a goroutine when a new connection is accepted
func handleClient(conn *net.TCPConn) {
	defer func() {
		if x := recover(); x != nil {
			ERR("caught panic in handleClient", x)
		}
	}()

	// input buffer
	config := cfg.Get()
	inqueue_size, err := strconv.Atoi(config["inqueue_size"])
	if err != nil {
		inqueue_size = DEFAULT_INQUEUE_SIZE
		WARN("cannot parse inqueue_size from config", err, "using default:", inqueue_size)
	}

	// init
	header := make([]byte, 2)
	in := make(chan []byte, inqueue_size)
	bufctrl := make(chan bool)

	defer func() {
		close(bufctrl)
		close(in)
	}()

	// create new session
	var sess Session
	sess.IP = net.ParseIP(strings.Split(conn.RemoteAddr().String(), ":")[0])
	NOTICE("new connection from:", sess.IP, "country:", geoip.Query(sess.IP))

	// create write buffer
	out := NewBuffer(&sess, conn, bufctrl)
	go out.Start()

	// start agent!!
	wg.Add(1)
	go StartAgent(&sess, in, out)

	for {
		// header
		conn.SetReadDeadline(time.Now().Add(TCP_TIMEOUT * time.Second))
		n, err := io.ReadFull(conn, header)
		if err != nil {
			WARN("error receiving header, bytes:", n, "reason:", err)
			break
		}

		// data
		size := binary.BigEndian.Uint16(header)
		data := make([]byte, size)
		n, err = io.ReadFull(conn, data)
		if err != nil {
			WARN("error receiving msg, bytes:", n, "reason:", err)
			break
		}

		// NOTICE: slice is passed by reference; don't re-use a single buffer.
		select {
		case in <- data:
		case <-time.After(MAX_DELAY_IN * time.Second):
			WARN("server busy or agent closed, session flag:", sess.Flag)
			return
		}
	}
}