Skip to content

Commit

Permalink
chore: Improve chatroom functionality
Browse files Browse the repository at this point in the history
- Enable user input capture and message sending using `bufio.NewScanner(os.Stdin)`
- Enhance broadcaster
- Add `getNew` function returning emojis name
- Implement WebSocket version similar to TCP

#17
  • Loading branch information
lc-1010 committed Jul 28, 2023
1 parent 1ab10ec commit a2b53a4
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 36 deletions.
6 changes: 3 additions & 3 deletions chatroom/cmd/tcp/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ func main() {
panic(err)
}

done := make(chan struct{})
//done := make(chan struct{})

go func() {
io.Copy(os.Stdout, conn)
log.Panicln("done")
done <- struct{}{}
//done <- struct{}{}
}()
mustCopy(conn, os.Stdin)
conn.Close()
<-done
//<-done

}
func mustCopy(dst io.Writer, src io.Reader) {
Expand Down
35 changes: 29 additions & 6 deletions chatroom/cmd/websocket/gobwas/client/clinet.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"bufio"
"context"
"log"
"os"
"time"

"github.com/gobwas/ws"
Expand All @@ -12,7 +14,7 @@ import (
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
conn, _, _, err := ws.Dial(ctx, "ws://localhost:8080")
conn, _, _, err := ws.Dial(ctx, "ws://localhost:8080/ws")
if err != nil {
log.Fatal(err)
}
Expand All @@ -21,11 +23,32 @@ func main() {
if err != nil {
log.Panicln(err)
}
msg, op, err := wsutil.ReadServerData(conn)
if err != nil {
log.Panicln(err)
go func() {
for {
msg, _, err := wsutil.ReadServerData(conn)
if err != nil {
log.Panicln(err)
}
log.Printf(">> %v\n", string(msg))
}
}()

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input := scanner.Bytes()
if err := wsutil.WriteClientText(conn, input); err != nil {
log.Printf("NewScanner %v\n", err)
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}

log.Printf("recv: %v,%v", string(msg), op)
conn.Close()
defer conn.Close()
}

// func mustCopy(dst io.Writer, src io.Reader) {
// if _, err := io.Copy(dst, src); err != nil {
// log.Fatal(err)
// }
// }
135 changes: 108 additions & 27 deletions chatroom/cmd/websocket/gobwas/server/server.go
Original file line number Diff line number Diff line change
@@ -1,62 +1,143 @@
package main

import (
"fmt"
"io"
"log"
"net"
"net/http"
"strconv"
"strings"

"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
emoji "github.com/tmdvs/Go-Emoji-Utils"
)

func main() {
userIdListChannel <- 0
go broadcaster()
http.HandleFunc("/ws", handleConn)
http.ListenAndServe(":8080", nil)
}

http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
conn, _, _, err := ws.UpgradeHTTP(r, w)
if err != nil {
panic(err)
}
go func() {
defer conn.Close()
for {
msg, op, err := wsutil.ReadClientData(conn)
if err != nil {
log.Printf("read:%v\n", err)
break
}
log.Println(msg)
func getID() int {
id := <-userIdListChannel
userIdListChannel <- id + 1
return id + 1
}

func handleConn(w http.ResponseWriter, r *http.Request) {
conn, _, _, err := ws.UpgradeHTTP(r, w)
if err != nil {
panic(err)
}

err = wsutil.WriteServerMessage(conn, op, []byte("Hello server"))
if err != nil {
log.Printf("write:%v\n", err)
break
user := User{
ID: getID(),
Name: getName(r.RemoteAddr),
conn: &conn,
}
enteringChannel <- user
wsutil.WriteServerMessage(conn, ws.OpText,
[]byte(fmt.Sprintf("%s,%s!", "hello", user.Name)))

go func(leavingChannel chan User) {
defer func() {
leavingChannel <- user
conn.Close()
}()
for {
msg, _, err := wsutil.ReadClientData(conn)
if err != nil {
if err != io.EOF {
log.Println(err)
}
break
}
}()
}))
log.Println(string(msg))
newMsg := fmt.Sprintf("[%d-%s]:%s", user.ID, user.Name, string(msg))
messageChannel <- []byte(newMsg)
}

}(leavingChannel)
}

var (
messageChannel = make(chan string, 8)
messageChannel = make(chan []byte, 8)
userIdListChannel = make(chan int, 1)
closeChannel = make(chan struct{})
enteringChannel = make(chan User)
leavingChannel = make(chan User)
//closeChannel = make(chan struct{})
enteringChannel = make(chan User)
leavingChannel = make(chan User)
)

type User struct {
ID int
Name string
Addr string
Msg chan string
conn *net.Conn
}

func broadcaster() {
usersMap := make(map[*User]struct{})
for {
select {
case user := <-enteringChannel:
userIdListChannel <- user.ID
case user := <-leavingChannel:
delete(usersMap, &user)
//userIdListChannel <- user.ID 没有一值处理结果满了阻塞了
usersMap[&user] = struct{}{}
log.Println(user.ID, "enter", len(usersMap))
case lu := <-leavingChannel:
delete(usersMap, &lu)
log.Println(lu.ID, "leave")
case msg := <-messageChannel:
log.Println("got messge", len(usersMap))
for user := range usersMap {
if strings.Split(strings.Trim(string(msg), "["), "-")[0] != strconv.Itoa(user.ID) {
err := wsutil.WriteServerMessage(*user.conn, ws.OpText, []byte(msg))
if err != nil {
log.Printf("write:%v\n", err)
delete(usersMap, user)
continue
}
}
}
log.Println("send done")
}

}
}

func getName(s string) string {

// 1. 提取数字
numStr := strings.Split(s, ":")[3]
num, _ := strconv.ParseInt(numStr, 10, 64)
fmt.Println(numStr, num, s)
// 2. 转16进制
hex := fmt.Sprintf("%X", num)

// 3. 转整数
val, _ := strconv.ParseInt(hex, 16, 32)
// 4. 检查范围
// 5. 映射到范围内
valTmp := val>>10 + 0x1F600
fmt.Println("tmp", valTmp)
// 6. 检查返回的emoji是否合法
for i := 0; i < 5; i++ {
e, err := emoji.LookupEmoji(string(rune(val)))
fmt.Printf("ok-->%#v %v\n", e, err)
if err == nil {
return e.Value
} else {
val = valTmp
}

val++

}
fmt.Println(val, "ooooo")
// 8. 还是无法获取,返回默认emoji
return string(rune(0x1F601))

}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tmdvs/Go-Emoji-Utils v1.1.0
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.4.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
Expand Down Expand Up @@ -734,6 +736,8 @@ github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+z
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
github.com/tmdvs/Go-Emoji-Utils v1.1.0 h1:gtPix7HZPrd49+MNDcuRLvv4xVNxCE5wgjqyuvmbyYg=
github.com/tmdvs/Go-Emoji-Utils v1.1.0/go.mod h1:J82i2WeGn+Kz+T3s5v9+i/OJlvevIVfGZ6qXgqiNWBc=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
Expand Down

0 comments on commit a2b53a4

Please sign in to comment.