Advertisement
Guest User

Untitled

a guest
Jun 9th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.39 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "net/http"
  5.     "fmt"
  6.     "github.com/gorilla/websocket"
  7.     "log"
  8.     "strings"
  9.     "sync"
  10. )
  11.  
  12. type WebSocketServer struct {
  13.     register chan *Client
  14.     unregister chan *Client
  15.     clients map[*Client]bool
  16.     broadcast chan []byte
  17. }
  18.  
  19. func (ws *WebSocketServer) Run() {
  20.     for {
  21.         select {
  22.         case client, isOk := <- ws.register:
  23.             if !isOk {
  24.                 log.Fatal("channel is closed, exiting")
  25.             }
  26.  
  27.             ws.broadcast <- []byte(fmt.Sprintf("client %v joined\n", client.Name()))
  28.             ws.clients[client] = true
  29.             fmt.Printf("player %v joined\n", client)
  30.         case client, isOk := <- ws.unregister:
  31.             if !isOk {
  32.                 log.Fatal("channel is closed, exiting")
  33.             }
  34.  
  35.             delete(ws.clients, client)
  36.             close(client.send)
  37.  
  38.             ws.broadcast <- []byte(fmt.Sprintf("client %v left\n", client.Name()))
  39.  
  40.             fmt.Printf("player %v left\n", client)
  41.         case msg, isOk := <- ws.broadcast:
  42.             if !isOk {
  43.                 log.Fatal("channel is closed, exiting")
  44.             }
  45.  
  46.             for client, _ := range ws.clients {
  47.                 client.send <- msg
  48.                 fmt.Println(client)
  49.             }
  50.  
  51.             fmt.Printf("broadcasting msg: %v\n", string(msg))
  52.         }
  53.     }
  54. }
  55.  
  56. type Client struct{
  57.     server *WebSocketServer
  58.     ws *websocket.Conn
  59.     lock *sync.Mutex
  60.     send chan []byte
  61.     name string
  62. }
  63.  
  64. func (c *Client) Name() string {
  65.     c.lock.Lock()
  66.     name := c.name
  67.     c.lock.Unlock()
  68.  
  69.     return name
  70. }
  71.  
  72. func (c *Client) SetName(name string) bool {
  73.     c.lock.Lock()
  74.     oldName := c.name
  75.     c.lock.Unlock()
  76.  
  77.     if oldName == name || strings.TrimSpace(name) == "" {
  78.         return false
  79.     }
  80.  
  81.     c.lock.Lock()
  82.     c.name = name
  83.     c.lock.Unlock()
  84.  
  85.     return true
  86. }
  87.  
  88. func (c *Client) read() {
  89.     defer func() {
  90.         c.server.unregister <- c
  91.         c.ws.Close()
  92.         fmt.Printf("exit read for %v\n", c.Name())
  93.     }()
  94.  
  95.     for {
  96.         _, msg, err := c.ws.ReadMessage()
  97.         if err != nil {
  98.             fmt.Println(err)
  99.             return
  100.         }
  101.  
  102.         if strings.HasPrefix(string(msg), "name:") {
  103.             name := strings.SplitN(string(msg), ":", 2)[1]
  104.             name = strings.TrimSpace(name)
  105.  
  106.             oldName := c.Name()
  107.  
  108.             if ok := c.SetName(name); ok {
  109.                 c.server.broadcast <- []byte(fmt.Sprintf("user %v changed name to %v\n", oldName, name))
  110.             }
  111.  
  112.             continue
  113.         }
  114.  
  115.  
  116.         c.server.broadcast <- []byte(fmt.Sprintf("%v: %s\n", c.Name(), msg))
  117.     }
  118. }
  119.  
  120. func (c *Client) write() {
  121.     defer func() {
  122.         c.ws.Close()
  123.         fmt.Printf("exit write for %v\n", c)
  124.     }()
  125.  
  126.     for {
  127.         select {
  128.         case msg, ok := <- c.send:
  129.             if !ok {
  130.                 return
  131.             }
  132.  
  133.             err := c.ws.WriteMessage(websocket.TextMessage, msg)
  134.             if err != nil {
  135.                 fmt.Println(err)
  136.                 return
  137.             }
  138.         }
  139.     }
  140. }
  141.  
  142. func main() {
  143.     server := &WebSocketServer{
  144.         register: make(chan *Client),
  145.         unregister: make(chan *Client),
  146.         clients: make(map[*Client]bool),
  147.         broadcast: make(chan []byte, 1),
  148.     }
  149.     go server.Run()
  150.  
  151.     wsUpgrader := websocket.Upgrader{
  152.         WriteBufferSize: 1024,
  153.         ReadBufferSize: 1024,
  154.     }
  155.  
  156.     http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  157.         http.ServeFile(w, r, "static/index.html")
  158.     })
  159.  
  160.     http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
  161.         wsCon, err := wsUpgrader.Upgrade(w,r,nil)
  162.         if err != nil {
  163.             fmt.Println(err)
  164.             return
  165.         }
  166.  
  167.         client := &Client{
  168.             server: server,
  169.             ws: wsCon,
  170.             send:make(chan []byte),
  171.             lock : &sync.Mutex{},
  172.         }
  173.  
  174.         client.name = fmt.Sprintf("%v", client)
  175.  
  176.         go client.read()
  177.         go client.write()
  178.  
  179.         client.server.register <- client
  180.     })
  181.  
  182.     fmt.Println(http.ListenAndServe(":8080", nil))
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement