Beispiel #1
0
// message fetcher
func fetcher_task() {
	//connect to game service
	clients, err := services.GetAllService(services.SERVICE_GAME)
	if err != nil {
		log.Critical(err)
		os.Exit(-1)
	}
	for _, cli := range clients {
		service, _ := cli.(proto.GameServiceClient)
		stream, err := service.Notify(context.Background(), &proto.Game_Nil{})
		if err != nil {
			log.Critical(err)
			os.Exit(-1)
		}
		go func() {
			for {
				p, err := stream.Recv()
				if err == io.EOF {
					log.Infof("stream recv EOF err :%v", err)
					return
				}
				if err != nil {
					log.Critical("stream recv gs err", err)
					continue
				}
				registry.Deliver(p.Uid, p.Content)
			}
		}()
	}
}
Beispiel #2
0
func (f *forwarder) recv(key string, cli GameService_PacketClient) {
	for {
		in, err := cli.Recv()
		if err == io.EOF {
			log.Infof("stream recv EOF err : %v", err)
			return
		}
		if err != nil {
			log.Critical("Failed to receive a note : %v", err)
			continue
		}
		registry.Deliver(in.Uid, in.Content)
	}
}
Beispiel #3
0
// start a goroutine when a new connection is accepted
func handleClient(conn *net.TCPConn) {
	defer utils.PrintPanicStack()
	// set per-connection socket buffer
	conn.SetReadBuffer(SO_RCVBUF)

	// set initial socket buffer
	conn.SetWriteBuffer(SO_SNDBUF)

	// initial network control struct
	header := make([]byte, 2)
	in := make(chan []byte)
	defer func() {
		close(in) // session will close
	}()

	// create a new session object for the connection
	var sess Session
	host, port, err := net.SplitHostPort(conn.RemoteAddr().String())
	if err != nil {
		log.Error("cannot get remote address:", err)
		return
	}
	sess.IP = net.ParseIP(host)
	log.Infof("new connection from:%v port:%v", host, port)

	// session die signal
	sess_die := make(chan bool)

	// create a write buffer
	out := new_buffer(conn, sess_die)
	go out.start()

	// start one agent for handling packet
	wg.Add(1)
	go agent(&sess, in, out, sess_die)

	// network loop
	for {
		// solve dead link problem
		conn.SetReadDeadline(time.Now().Add(TCP_READ_DEADLINE * time.Second))
		n, err := io.ReadFull(conn, header)
		if err != nil {
			log.Warningf("read header failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}
		size := binary.BigEndian.Uint16(header)

		// alloc a byte slice for reading
		payload := make([]byte, size)
		// read msg
		n, err = io.ReadFull(conn, payload)
		if err != nil {
			log.Warningf("read payload failed, ip:%v reason:%v size:%v", sess.IP, err, n)
			return
		}

		select {
		case in <- payload: // payload queued
		case <-sess_die:
			log.Warningf("connection closed by logic, flag:%v ip:%v", sess.Flag, sess.IP)
			return
		}
	}
}