예제 #1
0
파일: handler.go 프로젝트: emersion/miko
// Listen to a remote stream
func (h *Handler) Listen(conn *message.Conn) {
	defer (func() {
		// Will be executed when the connection is closed

		conn.Close()

		var session *message.Session
		if h.ctx.IsServer() {
			session = h.ctx.Auth.GetSession(conn.Id)
			if session != nil {
				h.ctx.Auth.Logout(conn.Id)
				conn.Broadcast(func(w io.Writer) error {
					return builder.SendPlayerLeft(w, h.ctx.Clock.GetRelativeTick(), session.Entity.Id)
				})
			}
		}
		if h.ctx.IsClient() {
			session = h.ctx.Me
		}

		if session != nil && session.Entity != nil {
			// TODO: move this elsewhere
			h.ctx.Entity.Delete(session.Entity.Id, h.ctx.Clock.GetAbsoluteTick())
		}
	})()

	var msgType message.Type
	for {
		err := read(conn, &msgType)
		if err == io.EOF {
			log.Println("Connection closed.")
			return
		} else if err != nil {
			log.Println("binary.Read failed:", err)
			return
		}

		done := make(chan error, 1)
		go func() {
			done <- h.Handle(msgType, conn)
		}()

		select {
		case err = <-done:
			if err != nil {
				log.Printf("Message handling failed for %q: %v\n", message.GetTypeName(msgType), err)
				return
			}
		case <-time.After(time.Second * 15):
			log.Printf("Message handling timed out for %q\n", message.GetTypeName(msgType))
			err = fmt.Errorf("Message handling timed out for %q", message.GetTypeName(msgType))
			return
		}
	}
}
예제 #2
0
func TestMetaAction_PlayerLeft(t *testing.T) {
	code := message.MetaActionCodes["player_left"]
	tick := message.Tick(42)
	entityId := message.EntityId(69)

	testMessage(t, message.Types["meta_action"], func(w io.Writer) error {
		return builder.SendPlayerLeft(w, tick, entityId)
	}, func(conn *message.Conn, t *testing.T) {
		rt, id, c, _ := handler.ReadMetaAction(conn)
		if rt != tick {
			t.Fatal("Sent tick", tick, "but received", rt)
		}
		if id != entityId {
			t.Fatal("Sent entity id", entityId, "but received", id)
		}
		if c != code {
			t.Fatal("Sent code", code, "but received", c)
		}
	})
}