Пример #1
0
func CreateHandler(user *User, data []byte) {

	// request body unmarshaling
	req := new(gs_protocol.ReqCreate)
	err := proto.Unmarshal(data, req)
	gs.CheckError(err)

	if user.userID != req.GetUserID() {
		if DEBUG {
			gs.Log("Fail room create, user id missmatch")
		}
		return
	}

	// room create
	roomID := GetRandomRoomID()
	r := NewRoom(roomID)
	r.users.Set(user.userID, user) // insert user
	user.room = r                  // set room
	rooms.Set(roomID, r)           // set room into global shared map
	if DEBUG {
		gs.Log("Get rand room id : ", gs.Itoa64(roomID))
	}
	// response body marshaling
	res := new(gs_protocol.ResCreate)
	res.RoomID = proto.Int64(roomID)
	res.UserID = proto.Int64(user.userID)

	if DEBUG {
		gs.Log("Room create, room id : ", gs.Itoa64(roomID))
	}
	msg, err := proto.Marshal(res)
	gs.CheckError(err)
	user.Push(NewMessage(user.userID, gs_protocol.Type_Create, msg))
}
Пример #2
0
func ClientReader(user *User, c net.Conn) {

	data := make([]byte, 4096) // 4096 byte slice (dynamic resize)

	for {
		n, err := c.Read(data)
		if err != nil {
			if DEBUG {
				gs.Log("Fail Stream read, err : ", err)
			}
			break
		}

		// header - body format (header + body in single line)
		messageType := gs_protocol.Type(gs.ReadInt32(data[0:4]))
		if DEBUG {
			gs.Log("Decoding type : ", messageType)
		}

		rawData := data[4:n] // 4~ end of line <--if fail read rawData, need calculated body size data (field)
		handler, ok := msgHandlerMapping[messageType]

		if ok {
			handler(user, rawData) // calling proper handler function
		} else {
			if DEBUG {
				gs.Log("Fail no function defined for type", handler)
			}
			break
		}
	}

	// fail read
	user.exit <- struct{}{}
}
Пример #3
0
func ClientSender(user *User, c net.Conn) {

	defer user.Leave()

	for {
		select {
		case <-user.exit:
			// when receive signal then finish the program
			if DEBUG {
				gs.Log("Leave user id :" + gs.Itoa64(user.userID))
			}
			return
		case m := <-user.recv:
			// on receive message
			msgTypeBytes := gs.WriteMsgType(m.msgType)

			// msg header + msg type
			msg := append(msgTypeBytes, m.content...) // '...' need when concat between slice+slice
			if DEBUG {
				gs.Log("Client recv, user id : " + gs.Itoa64(user.userID))
			}
			_, err := c.Write(msg) // send data to client
			if err != nil {
				if DEBUG {
					gs.Log(err)
				}
				return
			}
		}
	}
}
Пример #4
0
func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())
	ln, err := net.Listen("tcp", ":8000") // using TCP protocol over 8000 port
	if err != nil {
		if DEBUG {
			gs.Log(err)
		}
		return
	}

	InitRooms()

	defer ln.Close() // reserve listen wait close
	for {
		conn, err := ln.Accept() // server accept client connection -> return connection
		if err != nil {
			gs.Log("Fail Accept err : ", err)
			continue
		}
		defer conn.Close() // reserve tcp connection close

		go ClientHandler(conn)
	}
}
Пример #5
0
func Action1Handler(user *User, data []byte) {

	// request body unmarshaling
	req := new(gs_protocol.ReqAction1)
	err := proto.Unmarshal(data, req)
	gs.CheckError(err)

	// TODO create business logic for Action1 Type
	if DEBUG {
		gs.Log("Action1 userID : ", gs.Itoa64(req.GetUserID()))
	}

	// broadcast message
	notifyMsg := new(gs_protocol.NotifyAction1Msg)
	notifyMsg.UserID = proto.Int64(user.userID)
	msg, err := proto.Marshal(notifyMsg)
	gs.CheckError(err)

	user.SendToAll(NewMessage(user.userID, gs_protocol.Type_NotifyAction1, msg))

	// response body marshaling
	res := new(gs_protocol.ResAction1)
	res.UserID = proto.Int64(user.userID)
	res.Result = proto.Int32(1) // is success?
	msg, err = proto.Marshal(res)
	gs.CheckError(err)
	user.Push(NewMessage(user.userID, gs_protocol.Type_DefinedAction1, msg))
}
Пример #6
0
func GetRoom(roomID int64) (r *Room) {
	value, ok := rooms.Get(roomID)

	if !ok {
		if DEBUG {
			gs.Log("err: not exist room : ", roomID)
		}
	}
	r = value.(*Room)
	return
}
Пример #7
0
// On Client Connect
func ClientHandler(c net.Conn) {

	if DEBUG {
		gs.Log("New Connection: ", c.RemoteAddr())
	}

	gs.WriteScribe("access", "test")
	user := NewUser(0, nil) // empty user data
	go ClientReader(user, c)
	go ClientSender(user, c)
}
Пример #8
0
func GetRandomRoomID() (uuid int64) {
	for {
		// TODO change room-id generate strategy
		uuid = int64(gs.RandInt32(1, math.MaxInt32))
		if _, ok := rooms.Get(uuid); ok {
			if DEBUG {
				gs.Log("err: exist same room id")
			}
			continue
		}
		return
	}
}
Пример #9
0
func (r *Room) RoomMessageLoop() {
	// when messages channel is closed then "for-loop" will be break
	for m := range r.messages {
		for userID, _ := range r.users.Map() {
			if userID != m.userID {
				value, ok := r.users.Get(userID)
				if ok {
					user := value.(*User)
					if DEBUG {
						gs.Log("Push message for broadcast :" + gs.Itoa64(user.userID))
					}
					user.Push(m)
				}
			}
		}
	}
}
Пример #10
0
func JoinHandler(user *User, data []byte) {

	// request body unmarshaling
	req := new(gs_protocol.ReqJoin)
	err := proto.Unmarshal(data, req)
	gs.CheckError(err)

	roomID := req.GetRoomID()

	value, ok := rooms.Get(roomID)

	if !ok {
		if DEBUG {
			gs.Log("Fail room join, room does not exist, room id : ", gs.Itoa64(roomID))
		}
		return
	}

	r := value.(*Room)
	r.users.Set(user.userID, user)
	user.room = r

	// broadcast message
	notifyMsg := new(gs_protocol.NotifyJoinMsg)
	notifyMsg.UserID = proto.Int64(user.userID)
	notifyMsg.RoomID = proto.Int64(roomID)
	msg, err := proto.Marshal(notifyMsg)
	gs.CheckError(err)

	user.SendToAll(NewMessage(user.userID, gs_protocol.Type_NotifyJoin, msg))

	// response body marshaling
	res := new(gs_protocol.ResJoin)
	res.UserID = proto.Int64(user.userID)
	res.RoomID = proto.Int64(roomID)
	res.Members = r.getRoomUsers()

	msg, err = proto.Marshal(res)
	gs.CheckError(err)
	user.Push(NewMessage(user.userID, gs_protocol.Type_Join, msg))
}
Пример #11
0
func main() {
	client, err := net.Dial("tcp", "127.0.0.1:8000")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer client.Close()

	data := make([]byte, 4096)
	exit := make(chan struct{})

	var userID int64
	var method int
	fmt.Println("=================================================================")
	fmt.Println(" Input user ID (it must be a whole number greater than 0")
	fmt.Println("=================================================================")
	fmt.Print("userID : ")
	fmt.Scanln(&userID)

	ReqLogin(client, userID, data)

	go func() {
		for {
			fmt.Println("=================================================================")
			fmt.Println(" Input command number (1~5)")
			fmt.Println("=================================================================")
			fmt.Println("1. room list")
			fmt.Println("2. room create")
			fmt.Println("3. join")
			fmt.Println("4. action1")
			fmt.Println("5. quit")
			fmt.Print("choose number: ")
			fmt.Scanln(&method)

			switch method {
			case 1:
				ReqRoomList(client, userID, data)
			case 2:
				ReqCreate(client, userID, data)
			case 3:
				var roomID int64
				fmt.Print("input room id : ")
				fmt.Scanln(&roomID)
				ReqJoin(client, userID, data, roomID)
			case 4:
				ReqAction1(client, userID, data)
			case 5:
				ReqQuit(client, userID, data)
				fmt.Println("program exit..bye")
				exit <- struct{}{}
				return
			default:
				continue
			}
		}
	}()

	go func() {
		data := make([]byte, 4096)

		for {
			n, err := client.Read(data)
			if err != nil {
				gs.Log("Fail Stream read, err : ", err)
				break
			}

			messageType := gs_protocol.Type(gs.ReadInt32(data[0:4]))
			gs.Log("Decoding type : ", messageType)

			rawData := data[4:n]
			handler, ok := msgHandlerMapping[messageType]

			if ok {
				handler(rawData)
			} else {
				gs.Log("Fail no function defined for type", handler)
				break
			}
		}
	}()

	<-exit
}