func (h *hub) leave(s sockjs.Session, user *store.User) { h.ch <- func() { us := h.users[user.Id] if us == nil { return } delete(us.sess, s.ID()) log.Printf("exit: %s", user.Name) } }
func (h *hub) enter(s sockjs.Session, user *store.User) { h.ch <- func() { us := h.users[user.Id] if us == nil { us = &userSession{ user: user, sess: map[string]sockjs.Session{}, } h.users[user.Id] = us } us.sess[s.ID()] = s log.Printf("enter: %s", user.Name) } }
func Register(session sockjs.Session, oldId string, name string) error { if player, ok := FindPlayer(oldId); ok { player.Update(session, session.ID(), name) fmt.Println("Find an existed player & update it") return nil } else { if p := FindPlayerByName(name); p != nil { return NewError("The name is already registered!") } id := session.ID() players[id] = &GamePlayer{id, name, 0, &session, nil, nil, nil, false} fmt.Println("Register as new") return nil } }
func echoHandler(session sockjs.Session) { log.Println("new sockjs session established") var closedSession = make(chan struct{}) session.Send(session.ID()) go func() { reader, _ := chat.SubChannel(nil) for { select { case <-closedSession: return case msg := <-reader: if err := session.Send(msg.(string)); err != nil { return } } } }() for { if msg, err := session.Recv(); err == nil { data := &WSDataSchema{} buf := bytes.NewBufferString(msg) err = json.Unmarshal(buf.Bytes(), data) if err == nil { _type := data.Type _endpoint := data.Endpoint _id := data.Id if _type == "container" { session.Send(_endpoint + _id) break } } chat.Publish(msg) //session.Send(msg) continue } break } close(closedSession) log.Println("sockjs session closed") }
func handleMsg(session sockjs.Session, msg string) { fmt.Println("Message :", msg) decoder := json.NewDecoder(strings.NewReader(msg)) message := new(Message) decoder.Decode(message) if message.Confirm { fmt.Println("Received confirm message : " + msg + " , from " + session.ID()) return } switch message.Cmd { case CmdCreateGroup: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) createInfo := new(CreateGroupMesssage) decoder.Decode(createInfo) game := GetGame(createInfo.Game) if ok, err := player.CreateGroup(game, createInfo.Max, createInfo.AllowSpectator); ok { SendStructMessage(session, message.Cmd, struct { ID string `json:"groupId"` Hoster bool `json:"isHoster"` OK bool `json:"ok"` }{ID: player.GroupHosted.ID, Hoster: true, OK: true}, true) NotifyGroupListToAll() } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdJoinGroup: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) joinInfo := new(JoinGroupMessage) decoder.Decode(joinInfo) if ok, err := player.JoinGroup(joinInfo.GroupId); ok { SendStructMessage(session, message.Cmd, struct { ID string `json:"groupId"` OK bool `json:"ok"` }{ID: player.GroupJoined.ID, OK: true}, true) NotifyGroupListToAll() } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdExitGroup: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) exitInfo := new(ExitGroupMessage) decoder.Decode(exitInfo) if ok, err := player.ExitGroup(exitInfo.GroupId); ok { SendStructMessage(session, message.Cmd, struct { OK bool `json:"ok"` }{OK: true}, true) NotifyGroupListToAll() } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdRegister: decoder := json.NewDecoder(strings.NewReader(message.Msg)) registerInfo := new(RegisterMessage) decoder.Decode(registerInfo) if err := Register(session, registerInfo.ID, registerInfo.Name); err == nil { SendStructMessage(session, message.Cmd, struct { ID string `json:"id"` Name string `json:"name"` OK bool `json:"ok"` }{session.ID(), registerInfo.Name, true}, true) NotifyGroupListToAll() } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } CheckPlayingGame(registerInfo.ID, session.ID()) case CmdStartGame: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) startGameMessage := new(StartGameMessage) decoder.Decode(startGameMessage) group := player.GroupHosted if group == nil { err := NewError("You haven't hosted a group.") SendErrorMessage(session, message.Cmd, err.Error(), false, true) } if err := StartGame(group, startGameMessage.GroupId); err == nil { //Notify all player to action group.NotifyPlayer(message.Cmd, struct { OK bool `json:"ok"` }{true}) } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdGetData: if player, ok := FindPlayer(session.ID()); ok { if err := GetDataForPlayer(player); err != nil { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdPlayerAction: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) dataUpdateMessage := new(DataUpdateMessage) decoder.Decode(dataUpdateMessage) if player.GroupJoined != nil { if err := UpdateData(player, player.GroupJoined, dataUpdateMessage.Action, dataUpdateMessage.Data); err == nil { SendStructMessage(session, message.Cmd, struct { OK bool `json:"ok"` }{true}, true) } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("You are not playing in the group") SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdQuitGame: if player, ok := FindPlayer(session.ID()); ok { NotifyGroupListToOne(player) } case CmdStopGame: if player, ok := FindPlayer(session.ID()); ok { if player.GroupHosted != nil { if player.GroupHosted.Playing { player.GroupHosted.Playing = false player.InGame = false for _, p := range player.GroupHosted.Players { p.InGame = false } player.GroupHosted.NotifyAllExcept(CmdHostStop, "", player) } } NotifyGroupListToOne(player) } case CmdGetGameList: SendStructMessage(session, message.Cmd, GetGameList(), true) case CmdSpectateGame: if player, ok := FindPlayer(session.ID()); ok { decoder := json.NewDecoder(strings.NewReader(message.Msg)) spectInfo := new(SpectateGroupMessage) decoder.Decode(spectInfo) if ok, err := player.SpectateGame(spectInfo.GroupId); ok { player.Index = 5 NotifyGroupListToSpectator(player) SendStructMessage(session, message.Cmd, struct { ID string `json:"groupId"` OK bool `json:"ok"` }{ID: player.GroupSpectating.ID, OK: true}, true) } else { SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } case CmdStopSpectating: if player, ok := FindPlayer(session.ID()); ok { if player.GroupSpectating != nil { for i, spectator := range player.GroupSpectating.Spectators { if player == spectator { player.GroupSpectating.Spectators = append(player.GroupSpectating.Spectators[:i], player.GroupSpectating.Spectators[i+1:]...) player.GroupSpectating = nil player.InGame = false player.Index = 0 NotifyGroupListToSpectator(player) return } } err := NewError("Not found the spectator ") SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } else { err := NewError("No user found with id " + session.ID()) SendErrorMessage(session, message.Cmd, err.Error(), false, true) } } }
func Chat(session sockjs.Session) { glog.Info("Session started") sessionId := session.ID() chatSession := &ChatSession{ Id: sessionId, IsReady: false, Session: &session, } ChatSessions.Set(sessionId, chatSession) acceptedTypes := &map[string]string{ "image/jpeg": ".jpg", "image/jpg": ".jpg", "image/png": ".png", "image/gif": ".gif", } ticker := time.NewTicker(time.Second) // Not too nice, will be refactored later... online := func() { ready, chatting := ChatSessions.GetNumberOfReadyAndChatting() msg := &ChatMessage{ "event": "online", "r": ready, "c": chatting, } out, _ := json.Marshal(msg) body := string(out) session.Send(body) } go func() { for _ = range ticker.C { online() } }() online() for { if msg, err := session.Recv(); err == nil { var data ChatMessage json.Unmarshal([]byte(msg), &data) switch data["event"] { case "ready": ChatReady(sessionId, data["region"].(string)) case "typing": ChatSessions.Action(func() { chatSession.Room.BroadcastOthers(sessionId, "typing", strconv.FormatBool(data["typing"].(bool))) }) case "send": ChatSessions.Action(func() { chatSession.Room.BroadcastOthers(sessionId, "message", data["message"].(string)) }) case "exit": ChatSessions.Action(func() { glog.Info("Chat session ended") chatSession.Room.BroadcastOthers(sessionId, "exit", "") for i, _ := range chatSession.Room.Sessions { s := chatSession.Room.Sessions[i] if s != chatSession { s.Room = nil } //s.IsReady = true } chatSession.Room = nil }) case "picture": glog.Info("Picture received") ChatSessions.Action(func() { chatSession.Room.BroadcastOthers(sessionId, "picturebefore", "true") dataURL, err := dataurl.DecodeString(data["data"].(string)) if err != nil { glog.Error("Problem decoding file: ", err) } filename := helpers.GetRandomString(8) mt := dataURL.ContentType() if ext, ok := (*acceptedTypes)[mt]; ok { err = ioutil.WriteFile(MediaContent+filename+ext, dataURL.Data, 0644) if err != nil { glog.Error("Error saving file: ", err) } chatSession.Room.BroadcastOthers(sessionId, "picture", data["data"].(string)) } }) } continue } break } ticker.Stop() ChatSessions.Close(sessionId) glog.Info("Session closed") }