mirror of https://github.com/gorilla/websocket.git
command line chat example
This commit is contained in:
parent
1bddf2e0db
commit
3136bd00ef
|
@ -0,0 +1,81 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
connUserId := rand.Intn(100)
|
||||
header := http.Header{}
|
||||
header.Add("user-id", fmt.Sprint(connUserId))
|
||||
|
||||
dialer := websocket.Dialer{}
|
||||
conn, _, err := dialer.Dial("ws://localhost:4000", header)
|
||||
if err != nil {
|
||||
err := conn.WriteMessage(websocket.CloseMessage,
|
||||
websocket.FormatCloseMessage(websocket.CloseInternalServerErr, err.Error()))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for range c {
|
||||
err := conn.WriteMessage(websocket.CloseMessage,
|
||||
websocket.FormatCloseMessage(websocket.CloseNormalClosure,
|
||||
fmt.Sprintf("User %d closing connection", connUserId)))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}()
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
go func() {
|
||||
for {
|
||||
fmt.Print(fmt.Sprintf("%d: ", connUserId))
|
||||
text, _ := reader.ReadString('\n')
|
||||
|
||||
err = conn.WriteMessage(websocket.TextMessage, []byte(text))
|
||||
if err != nil {
|
||||
err := conn.WriteMessage(websocket.CloseMessage,
|
||||
websocket.FormatCloseMessage(websocket.CloseInternalServerErr, err.Error()))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
_, p, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
err := conn.WriteMessage(websocket.CloseInternalServerErr,
|
||||
websocket.FormatCloseMessage(websocket.CloseNormalClosure, err.Error()))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
fmt.Printf("\n%s", p)
|
||||
fmt.Print(fmt.Sprintf("%d: ", connUserId))
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
var connections = make(map[string]*websocket.Conn)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad Request", http.StatusBadRequest)
|
||||
fmt.Println("Upgrade error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
connUserId := r.Header.Get("user-id")
|
||||
connections[connUserId] = conn
|
||||
|
||||
alterCloseHandlerToRemoveConnections(conn, connUserId)
|
||||
|
||||
go func() {
|
||||
defer conn.Close()
|
||||
for {
|
||||
_, p, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
switch {
|
||||
case websocket.IsCloseError(err, websocket.CloseNormalClosure):
|
||||
err = broadcastMessage(fmt.Sprintf("User %s left the chat\n", connUserId), connUserId)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
}
|
||||
default:
|
||||
fmt.Println(err)
|
||||
err = broadcastMessage(fmt.Sprintf("User %s disconnected unexpectedly\n", connUserId), connUserId)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
}
|
||||
conn.CloseHandler()(websocket.CloseNormalClosure, "")
|
||||
}
|
||||
return
|
||||
}
|
||||
err = broadcastMessage(fmt.Sprintf("%s: %s", connUserId, p), connUserId)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
fmt.Println("Server started on :4000")
|
||||
err := http.ListenAndServe(":4000", nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func broadcastMessage(message, connUserId string) error {
|
||||
for cuid, con := range connections {
|
||||
if cuid != connUserId {
|
||||
err := con.WriteMessage(websocket.TextMessage, []byte(message))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func alterCloseHandlerToRemoveConnections(conn *websocket.Conn, connUserId string) {
|
||||
conn.SetCloseHandler(func(code int, text string) error {
|
||||
delete(connections, connUserId)
|
||||
message := websocket.FormatCloseMessage(code, "")
|
||||
if err := conn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue