Advertisement
Guest User

Untitled

a guest
Apr 24th, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.01 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "bufio"
  5.     "fmt"
  6.     "log"
  7.     "net"
  8.     "os"
  9.     "strconv"
  10.     "strings"
  11. )
  12.  
  13. var messages chan string
  14.  
  15. type Client struct {
  16.     Id      uint64
  17.     MsgChan chan (string)
  18. }
  19.  
  20. type ClientPool struct {
  21.     counter    uint64
  22.     joins      chan (Client)
  23.     lefts      chan (uint64)
  24.     ids        chan (uint64)
  25.     broadcasts chan (string)
  26.     clients    map[uint64]Client
  27. }
  28.  
  29. func NewClientPool() *ClientPool {
  30.     pool := ClientPool{
  31.         joins:      make(chan (Client)),
  32.         lefts:      make(chan (uint64)),
  33.         ids:        make(chan (uint64)),
  34.         broadcasts: make(chan (string)),
  35.         clients:    make(map[uint64]Client),
  36.     }
  37.  
  38.     go func() {
  39.         var id uint64
  40.         for {
  41.             id++
  42.             pool.ids <- id
  43.         }
  44.     }()
  45.  
  46.     go func() {
  47.         for {
  48.             select {
  49.             case newClient := <-pool.joins:
  50.                 pool.clients[newClient.Id] = newClient
  51.             case idForDeletion := <-pool.lefts:
  52.                 delete(pool.clients, idForDeletion)
  53.             case text := <-pool.broadcasts:
  54.                 for _, client := range pool.clients {
  55.                     client.MsgChan <- text
  56.                 }
  57.             }
  58.         }
  59.     }()
  60.  
  61.     return &pool
  62. }
  63.  
  64. func (this *ClientPool) NewClient() Client {
  65.     client := Client{
  66.         Id:      <-this.ids,
  67.         MsgChan: make(chan (string)),
  68.     }
  69.     this.joins <- client
  70.     return client
  71. }
  72.  
  73. func (this *ClientPool) BroadcastMessage(text string) {
  74.     this.broadcasts <- text
  75. }
  76.  
  77. func (this *ClientPool) DeleteClient(client Client) {
  78.     this.lefts <- client.Id
  79. }
  80.  
  81. func main() {
  82.     pool := NewClientPool()
  83.     var port int = 3333
  84.     listen, err := net.Listen("tcp4", ":"+strconv.Itoa(port))
  85.     defer listen.Close()
  86.     if err != nil {
  87.         log.Fatalf("Прослушивание порта %d не удалось,\r\n\r\n %s", port, err)
  88.         os.Exit(1)
  89.     }
  90.  
  91.     go func() {
  92.  
  93.         log.Printf("Сервер слушает порт: %d", port)
  94.         reader := bufio.NewReader(os.Stdin)
  95.         for {
  96.             fmt.Print("Enter text: ")
  97.             text, _ := reader.ReadString('\n')
  98.             log.Print(text)
  99.             pool.BroadcastMessage(text)
  100.         }
  101.  
  102.     }()
  103.  
  104.     for {
  105.         conn, err := listen.Accept()
  106.         if err != nil {
  107.             log.Fatalln(err)
  108.             continue
  109.         }
  110.         go handler(conn, pool)
  111.     }
  112. }
  113.  
  114. func handler(conn net.Conn, pool *ClientPool) {
  115.     client := pool.NewClient()
  116.     defer pool.DeleteClient(client)
  117.     defer conn.Close()
  118.     defer log.Printf("Клиент с номером %d вышел\n", client.Id)
  119.  
  120.     log.Printf("Новый клиент присоединен, ему присвоен номер %d", client.Id)
  121.  
  122.     incomingClientMsg := make(chan string)
  123.     exitSignal := make(chan bool)
  124.  
  125.     go func() {
  126.         reader := bufio.NewReader(conn)
  127.         for {
  128.             text, err := reader.ReadString('\n')
  129.             if err != nil {
  130.                 exitSignal <- true
  131.                 return
  132.             }
  133.             incomingClientMsg <- text
  134.         }
  135.     }()
  136.  
  137.     for {
  138.         select {
  139.         case <-exitSignal:
  140.             return
  141.         case text := <-incomingClientMsg:
  142.             text = strings.Trim(text, "\r\n")
  143.             if text == "/quit" {
  144.                 return
  145.             }
  146.             log.Printf("Клиент с номером %d написал: %s\n", client.Id, text)
  147.         case text := <-client.MsgChan:
  148.             _, err := conn.Write([]byte(text))
  149.             if err != nil {
  150.                 return
  151.             }
  152.         }
  153.     }
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement