{"action":"created","comment":{"url":"https://api.github.com/repos/gibsn/technochat/pulls/comments/197581755","pull_request_review_id":131349036,"id":197581755,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5NzU4MTc1NQ==","diff_hunk":"@@ -0,0 +1,200 @@\n+package http\n+\n+import (\n+\t\"encoding/json\"\n+\t\"io/ioutil\"\n+\t\"log\"\n+\t\"math/rand\"\n+\t\"net/http\"\n+\t\"time\"\n+\n+\t\"github.com/google/uuid\"\n+\t\"github.com/gorilla/websocket\"\n+)\n+\n+const DefaultMaxPPL = 2\n+\n+var chats = make(map[string]*Chat)\n+var upgrader = websocket.Upgrader{\n+\tCheckOrigin: func(r *http.Request) bool { return true },\n+}\n+\n+type Chat struct {\n+\tbroadcast chan WSMessage\n+\tcorresps  map[*User]bool\n+\tpplToJoin int\n+\tusedNames map[int]bool\n+}\n+\n+func (c *Chat) AddUser(ws *websocket.Conn) *User {\n+\tn := 0\n+\tusr := &User{WS: ws}\n+\tfor {\n+\t\tn = rand.Intn(len(RandomNames))\n+\t\tif !c.usedNames[n] {\n+\t\t\tusr.Username = RandomNames[n]\n+\t\t\tc.usedNames[n] = true\n+\t\t\tbreak\n+\t\t}\n+\t}\n+\n+\tc.corresps[usr] = true\n+\treturn usr\n+}\n+\n+type User struct {\n+\tWS       *websocket.Conn\n+\tUsername string\n+}\n+\n+type TypeID int\n+\n+const (\n+\tWSMsgTypeService TypeID = iota\n+\tWSMsgTypeMessage\n+)\n+\n+type Event struct {\n+\tEventID   EventID     `json:\"event_id\"`\n+\tEventData interface{} `json:\"event_data\"`\n+}\n+type EventID int\n+\n+const (\n+\tEventConnInitOk EventID = iota\n+\tEventConnInitNoSuchChat\n+\tEventConnInitMaxUsrReached\n+)\n+\n+type WSMessage struct {\n+\tType     TypeID      `json:\"type\"`\n+\tData     interface{} `json:\"data\"`\n+\tUsername string      `json:\"username\"`\n+}\n+\n+type OchatInitRequest struct {\n+\tMaxUsers int `json:\"max_users\"`\n+}\n+type OchatInitResponse struct {\n+\tId string `json:\"id\"`\n+}\n+\n+func (s *Server) ochatInit(r *http.Request) (int, interface{}, error) {\n+\tbody, err := ioutil.ReadAll(r.Body)\n+\tif err != nil {\n+\t\treturn http.StatusBadRequest, nil, err\n+\t}\n+\n+\treq := OchatInitRequest{MaxUsers: DefaultMaxPPL}\n+\tif len(body) != 0 {\n+\t\terr = json.Unmarshal(body, &req)\n+\t\tif err != nil {\n+\t\t\treturn http.StatusBadRequest, nil, err\n+\t\t}\n+\t}\n+\n+\t//generate chat id\n+\tchatID, err := uuid.NewRandom()\n+\tif err != nil {\n+\t\treturn http.StatusBadRequest, nil, err\n+\t}\n+\tchatIDStr := chatID.String()\n+\n+\t//init chat\n+\tchats[chatIDStr] = &Chat{\n+\t\tcorresps:  make(map[*User]bool),\n+\t\tbroadcast: make(chan WSMessage),\n+\t\tusedNames: make(map[int]bool),\n+\t\tpplToJoin: req.MaxUsers,\n+\t}\n+\n+\t//do broadcasts\n+\tgo func() {\n+\t\tfor {\n+\t\t\tselect {\n+\t\t\tcase <-time.After(360 * time.Second):\n+\t\t\t\tfor usr := range chats[chatIDStr].corresps { //TODO: refactor\n+\t\t\t\t\tusr.WS.Close()\n+\t\t\t\t\tdelete(chats[chatIDStr].corresps, usr)\n+\t\t\t\t}\n+\t\t\t\tdelete(chats, chatIDStr)\n+\t\t\t\treturn\n+\t\t\tcase msg := <-chats[chatIDStr].broadcast:\n+\t\t\t\tfor usr := range chats[chatIDStr].corresps {\n+\t\t\t\t\terr := usr.WS.WriteJSON(msg)\n+\t\t\t\t\tif err != nil {\n+\t\t\t\t\t\tlog.Printf(\"error broadcasting: %v\", err)\n+\t\t\t\t\t\tusr.WS.Close()\n+\t\t\t\t\t\tdelete(chats[chatIDStr].corresps, usr)\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}()\n+\n+\tresp := map[string]string{\n+\t\t\"id\": chatIDStr,\n+\t}\n+\treturn http.StatusOK, resp, nil\n+}\n+\n+func (s *Server) ochatConnect(w http.ResponseWriter, r *http.Request) {\n+\tws, err := upgrader.Upgrade(w, r, nil)\n+\tif err != nil {\n+\t\tlog.Printf(\"error upgrading chat connection: %v\", err)\n+\t}\n+\tdefer ws.Close()\n+\n+\terr = r.ParseForm()\n+\tif err != nil {\n+\t\tlog.Printf(\"error parsing form :%v\", err)\n+\t}\n+\tchatIDStr := r.FormValue(\"id\")\n+\n+\t//check chat existance\n+\tchat, ok := chats[chatIDStr]\n+\tif !ok {\n+\t\tlog.Printf(\"chat %s not exists\", chatIDStr)\n+\t\tsendEvent(ws, EventConnInitNoSuchChat, nil)\n+\t\treturn\n+\t} else if chat.pplToJoin <= 0 {\n+\t\tlog.Printf(\"chat %s max user reached\", chatIDStr)\n+\t\tsendEvent(ws, EventConnInitNoSuchChat, nil)\n+\t\treturn\n+\t}\n+\n+\tusr := chats[chatIDStr].AddUser(ws)\n+\tsendEvent(usr.WS, EventConnInitOk, usr.Username)\n+\n+\tsendServerNotify(chats[chatIDStr].broadcast, \"user \"+usr.Username+\" joined\")\n+\tchats[chatIDStr].pplToJoin--\n+\tfor {\n+\t\tmsg := WSMessage{\n+\t\t\tUsername: usr.Username,\n+\t\t}\n+\t\terr := usr.WS.ReadJSON(&msg)\n+\t\tif err != nil {\n+\t\t\tlog.Printf(\"error: %v\", err)\n+\t\t\tdelete(chats[chatIDStr].corresps, usr)\n+\n+\t\t\tsendServerNotify(chats[chatIDStr].broadcast, \"user \"+usr.Username+\" has left\")\n+\t\t\tbreak\n+\t\t}\n+\t\tchats[chatIDStr].broadcast <- msg\n+\t}\n+}\n+\n+func sendServerNotify(brcast chan WSMessage, str string) {","path":"src/technochat/http/ochat.go","position":193,"original_position":187,"commit_id":"52fffcbc13fbc6b4c57b05bed99027694f102dfb","original_commit_id":"93af1095b60845f08cccb0c11a1b34fb05b89cb0","user":{"login":"gibsn","id":11294101,"node_id":"MDQ6VXNlcjExMjk0MTAx","avatar_url":"https://avatars3.githubusercontent.com/u/11294101?v=4","gravatar_id":"","url":"https://api.github.com/users/gibsn","html_url":"https://github.com/gibsn","followers_url":"https://api.github.com/users/gibsn/followers","following_url":"https://api.github.com/users/gibsn/following{/other_user}","gists_url":"https://api.github.com/users/gibsn/gists{/gist_id}","starred_url":"https://api.github.com/users/gibsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gibsn/subscriptions","organizations_url":"https://api.github.com/users/gibsn/orgs","repos_url":"https://api.github.com/users/gibsn/repos","events_url":"https://api.github.com/users/gibsn/events{/privacy}","received_events_url":"https://api.github.com/users/gibsn/received_events","type":"User","site_admin":false},"body":"why not `broadcast`?","created_at":"2018-06-22T22:16:29Z","updated_at":"2018-06-22T23:02:24Z","html_url":"https://github.com/gibsn/technochat/pull/9#discussion_r197581755","pull_request_url":"https://api.github.com/repos/gibsn/technochat/pulls/9","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/comments/197581755"},"html":{"href":"https://github.com/gibsn/technochat/pull/9#discussion_r197581755"},"pull_request":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/9"}}},"pull_request":{"url":"https://api.github.com/repos/gibsn/technochat/pulls/9","id":194917973,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk0OTE3OTcz","html_url":"https://github.com/gibsn/technochat/pull/9","diff_url":"https://github.com/gibsn/technochat/pull/9.diff","patch_url":"https://github.com/gibsn/technochat/pull/9.patch","issue_url":"https://api.github.com/repos/gibsn/technochat/issues/9","number":9,"state":"open","locked":false,"title":"WIP: feature/issue_5_add_online_chat","user":{"login":"skinass","id":10638045,"node_id":"MDQ6VXNlcjEwNjM4MDQ1","avatar_url":"https://avatars2.githubusercontent.com/u/10638045?v=4","gravatar_id":"","url":"https://api.github.com/users/skinass","html_url":"https://github.com/skinass","followers_url":"https://api.github.com/users/skinass/followers","following_url":"https://api.github.com/users/skinass/following{/other_user}","gists_url":"https://api.github.com/users/skinass/gists{/gist_id}","starred_url":"https://api.github.com/users/skinass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skinass/subscriptions","organizations_url":"https://api.github.com/users/skinass/orgs","repos_url":"https://api.github.com/users/skinass/repos","events_url":"https://api.github.com/users/skinass/events{/privacy}","received_events_url":"https://api.github.com/users/skinass/received_events","type":"User","site_admin":false},"body":"#5 \r\nfetch vendor\r\ninit online chat api support \r\n","created_at":"2018-06-14T14:44:10Z","updated_at":"2018-06-22T23:02:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2b2e82c490aa73aaabd30de7efea87a5c91bca7e","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/gibsn/technochat/pulls/9/commits","review_comments_url":"https://api.github.com/repos/gibsn/technochat/pulls/9/comments","review_comment_url":"https://api.github.com/repos/gibsn/technochat/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gibsn/technochat/issues/9/comments","statuses_url":"https://api.github.com/repos/gibsn/technochat/statuses/52fffcbc13fbc6b4c57b05bed99027694f102dfb","head":{"label":"gibsn:feature/issue-5_add_online_chat","ref":"feature/issue-5_add_online_chat","sha":"52fffcbc13fbc6b4c57b05bed99027694f102dfb","user":{"login":"gibsn","id":11294101,"node_id":"MDQ6VXNlcjExMjk0MTAx","avatar_url":"https://avatars3.githubusercontent.com/u/11294101?v=4","gravatar_id":"","url":"https://api.github.com/users/gibsn","html_url":"https://github.com/gibsn","followers_url":"https://api.github.com/users/gibsn/followers","following_url":"https://api.github.com/users/gibsn/following{/other_user}","gists_url":"https://api.github.com/users/gibsn/gists{/gist_id}","starred_url":"https://api.github.com/users/gibsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gibsn/subscriptions","organizations_url":"https://api.github.com/users/gibsn/orgs","repos_url":"https://api.github.com/users/gibsn/repos","events_url":"https://api.github.com/users/gibsn/events{/privacy}","received_events_url":"https://api.github.com/users/gibsn/received_events","type":"User","site_admin":false},"repo":{"id":136743874,"node_id":"MDEwOlJlcG9zaXRvcnkxMzY3NDM4NzQ=","name":"technochat","full_name":"gibsn/technochat","owner":{"login":"gibsn","id":11294101,"node_id":"MDQ6VXNlcjExMjk0MTAx","avatar_url":"https://avatars3.githubusercontent.com/u/11294101?v=4","gravatar_id":"","url":"https://api.github.com/users/gibsn","html_url":"https://github.com/gibsn","followers_url":"https://api.github.com/users/gibsn/followers","following_url":"https://api.github.com/users/gibsn/following{/other_user}","gists_url":"https://api.github.com/users/gibsn/gists{/gist_id}","starred_url":"https://api.github.com/users/gibsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gibsn/subscriptions","organizations_url":"https://api.github.com/users/gibsn/orgs","repos_url":"https://api.github.com/users/gibsn/repos","events_url":"https://api.github.com/users/gibsn/events{/privacy}","received_events_url":"https://api.github.com/users/gibsn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gibsn/technochat","description":"Technochat is a simple web service that lets you create self-destructive messages with TTL","fork":false,"url":"https://api.github.com/repos/gibsn/technochat","forks_url":"https://api.github.com/repos/gibsn/technochat/forks","keys_url":"https://api.github.com/repos/gibsn/technochat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gibsn/technochat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gibsn/technochat/teams","hooks_url":"https://api.github.com/repos/gibsn/technochat/hooks","issue_events_url":"https://api.github.com/repos/gibsn/technochat/issues/events{/number}","events_url":"https://api.github.com/repos/gibsn/technochat/events","assignees_url":"https://api.github.com/repos/gibsn/technochat/assignees{/user}","branches_url":"https://api.github.com/repos/gibsn/technochat/branches{/branch}","tags_url":"https://api.github.com/repos/gibsn/technochat/tags","blobs_url":"https://api.github.com/repos/gibsn/technochat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gibsn/technochat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gibsn/technochat/git/refs{/sha}","trees_url":"https://api.github.com/repos/gibsn/technochat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gibsn/technochat/statuses/{sha}","languages_url":"https://api.github.com/repos/gibsn/technochat/languages","stargazers_url":"https://api.github.com/repos/gibsn/technochat/stargazers","contributors_url":"https://api.github.com/repos/gibsn/technochat/contributors","subscribers_url":"https://api.github.com/repos/gibsn/technochat/subscribers","subscription_url":"https://api.github.com/repos/gibsn/technochat/subscription","commits_url":"https://api.github.com/repos/gibsn/technochat/commits{/sha}","git_commits_url":"https://api.github.com/repos/gibsn/technochat/git/commits{/sha}","comments_url":"https://api.github.com/repos/gibsn/technochat/comments{/number}","issue_comment_url":"https://api.github.com/repos/gibsn/technochat/issues/comments{/number}","contents_url":"https://api.github.com/repos/gibsn/technochat/contents/{+path}","compare_url":"https://api.github.com/repos/gibsn/technochat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gibsn/technochat/merges","archive_url":"https://api.github.com/repos/gibsn/technochat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gibsn/technochat/downloads","issues_url":"https://api.github.com/repos/gibsn/technochat/issues{/number}","pulls_url":"https://api.github.com/repos/gibsn/technochat/pulls{/number}","milestones_url":"https://api.github.com/repos/gibsn/technochat/milestones{/number}","notifications_url":"https://api.github.com/repos/gibsn/technochat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gibsn/technochat/labels{/name}","releases_url":"https://api.github.com/repos/gibsn/technochat/releases{/id}","deployments_url":"https://api.github.com/repos/gibsn/technochat/deployments","created_at":"2018-06-09T17:22:53Z","updated_at":"2018-06-22T22:31:04Z","pushed_at":"2018-06-22T22:31:03Z","git_url":"git://github.com/gibsn/technochat.git","ssh_url":"git@github.com:gibsn/technochat.git","clone_url":"https://github.com/gibsn/technochat.git","svn_url":"https://github.com/gibsn/technochat","homepage":"","size":327,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":19,"license":null,"forks":0,"open_issues":19,"watchers":0,"default_branch":"master"}},"base":{"label":"gibsn:master","ref":"master","sha":"aa2e657337defca704f50dfcede6961a83057229","user":{"login":"gibsn","id":11294101,"node_id":"MDQ6VXNlcjExMjk0MTAx","avatar_url":"https://avatars3.githubusercontent.com/u/11294101?v=4","gravatar_id":"","url":"https://api.github.com/users/gibsn","html_url":"https://github.com/gibsn","followers_url":"https://api.github.com/users/gibsn/followers","following_url":"https://api.github.com/users/gibsn/following{/other_user}","gists_url":"https://api.github.com/users/gibsn/gists{/gist_id}","starred_url":"https://api.github.com/users/gibsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gibsn/subscriptions","organizations_url":"https://api.github.com/users/gibsn/orgs","repos_url":"https://api.github.com/users/gibsn/repos","events_url":"https://api.github.com/users/gibsn/events{/privacy}","received_events_url":"https://api.github.com/users/gibsn/received_events","type":"User","site_admin":false},"repo":{"id":136743874,"node_id":"MDEwOlJlcG9zaXRvcnkxMzY3NDM4NzQ=","name":"technochat","full_name":"gibsn/technochat","owner":{"login":"gibsn","id":11294101,"node_id":"MDQ6VXNlcjExMjk0MTAx","avatar_url":"https://avatars3.githubusercontent.com/u/11294101?v=4","gravatar_id":"","url":"https://api.github.com/users/gibsn","html_url":"https://github.com/gibsn","followers_url":"https://api.github.com/users/gibsn/followers","following_url":"https://api.github.com/users/gibsn/following{/other_user}","gists_url":"https://api.github.com/users/gibsn/gists{/gist_id}","starred_url":"https://api.github.com/users/gibsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gibsn/subscriptions","organizations_url":"https://api.github.com/users/gibsn/orgs","repos_url":"https://api.github.com/users/gibsn/repos","events_url":"https://api.github.com/users/gibsn/events{/privacy}","received_events_url":"https://api.github.com/users/gibsn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gibsn/technochat","description":"Technochat is a simple web service that lets you create self-destructive messages with TTL","fork":false,"url":"https://api.github.com/repos/gibsn/technochat","forks_url":"https://api.github.com/repos/gibsn/technochat/forks","keys_url":"https://api.github.com/repos/gibsn/technochat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gibsn/technochat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gibsn/technochat/teams","hooks_url":"https://api.github.com/repos/gibsn/technochat/hooks","issue_events_url":"https://api.github.com/repos/gibsn/technochat/issues/events{/number}","events_url":"https://api.github.com/repos/gibsn/technochat/events","assignees_url":"https://api.github.com/repos/gibsn/technochat/assignees{/user}","branches_url":"https://api.github.com/repos/gibsn/technochat/branches{/branch}","tags_url":"https://api.github.com/repos/gibsn/technochat/tags","blobs_url":"https://api.github.com/repos/gibsn/technochat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gibsn/technochat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gibsn/technochat/git/refs{/sha}","trees_url":"https://api.github.com/repos/gibsn/technochat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gibsn/technochat/statuses/{sha}","languages_url":"https://api.github.com/repos/gibsn/technochat/languages","stargazers_url":"https://api.github.com/repos/gibsn/technochat/stargazers","contributors_url":"https://api.github.com/repos/gibsn/technochat/contributors","subscribers_url":"https://api.github.com/repos/gibsn/technochat/subscribers","subscription_url":"https://api.github.com/repos/gibsn/technochat/subscription","commits_url":"https://api.github.com/repos/gibsn/technochat/commits{/sha}","git_commits_url":"https://api.github.com/repos/gibsn/technochat/git/commits{/sha}","comments_url":"https://api.github.com/repos/gibsn/technochat/comments{/number}","issue_comment_url":"https://api.github.com/repos/gibsn/technochat/issues/comments{/number}","contents_url":"https://api.github.com/repos/gibsn/technochat/contents/{+path}","compare_url":"https://api.github.com/repos/gibsn/technochat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gibsn/technochat/merges","archive_url":"https://api.github.com/repos/gibsn/technochat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gibsn/technochat/downloads","issues_url":"https://api.github.com/repos/gibsn/technochat/issues{/number}","pulls_url":"https://api.github.com/repos/gibsn/technochat/pulls{/number}","milestones_url":"https://api.github.com/repos/gibsn/technochat/milestones{/number}","notifications_url":"https://api.github.com/repos/gibsn/technochat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gibsn/technochat/labels{/name}","releases_url":"https://api.github.com/repos/gibsn/technochat/releases{/id}","deployments_url":"https://api.github.com/repos/gibsn/technochat/deployments","created_at":"2018-06-09T17:22:53Z","updated_at":"2018-06-22T22:31:04Z","pushed_at":"2018-06-22T22:31:03Z","git_url":"git://github.com/gibsn/technochat.git","ssh_url":"git@github.com:gibsn/technochat.git","clone_url":"https://github.com/gibsn/technochat.git","svn_url":"https://github.com/gibsn/technochat","homepage":"","size":327,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":19,"license":null,"forks":0,"open_issues":19,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/9"},"html":{"href":"https://github.com/gibsn/technochat/pull/9"},"issue":{"href":"https://api.github.com/repos/gibsn/technochat/issues/9"},"comments":{"href":"https://api.github.com/repos/gibsn/technochat/issues/9/comments"},"review_comments":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/9/comments"},"review_comment":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gibsn/technochat/pulls/9/commits"},"statuses":{"href":"https://api.github.com/repos/gibsn/technochat/statuses/52fffcbc13fbc6b4c57b05bed99027694f102dfb"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"gibsn"}}