Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "bufio"
- "fmt"
- "log"
- "net"
- "os"
- "strconv"
- "strings"
- )
- var messages chan string
- type Client struct {
- Id uint64
- MsgChan chan (string)
- }
- type ClientPool struct {
- counter uint64
- joins chan (Client)
- lefts chan (uint64)
- ids chan (uint64)
- broadcasts chan (string)
- clients map[uint64]Client
- }
- func NewClientPool() *ClientPool {
- pool := ClientPool{
- joins: make(chan (Client)),
- lefts: make(chan (uint64)),
- ids: make(chan (uint64)),
- broadcasts: make(chan (string)),
- clients: make(map[uint64]Client),
- }
- go func() {
- var id uint64
- for {
- id++
- pool.ids <- id
- }
- }()
- go func() {
- for {
- select {
- case newClient := <-pool.joins:
- pool.clients[newClient.Id] = newClient
- case idForDeletion := <-pool.lefts:
- delete(pool.clients, idForDeletion)
- case text := <-pool.broadcasts:
- for _, client := range pool.clients {
- client.MsgChan <- text
- }
- }
- }
- }()
- return &pool
- }
- func (this *ClientPool) NewClient() Client {
- client := Client{
- Id: <-this.ids,
- MsgChan: make(chan (string)),
- }
- this.joins <- client
- return client
- }
- func (this *ClientPool) BroadcastMessage(text string) {
- this.broadcasts <- text
- }
- func (this *ClientPool) DeleteClient(client Client) {
- this.lefts <- client.Id
- }
- func main() {
- pool := NewClientPool()
- var port int = 3333
- listen, err := net.Listen("tcp4", ":"+strconv.Itoa(port))
- defer listen.Close()
- if err != nil {
- log.Fatalf("Прослушивание порта %d не удалось,\r\n\r\n %s", port, err)
- os.Exit(1)
- }
- go func() {
- log.Printf("Сервер слушает порт: %d", port)
- reader := bufio.NewReader(os.Stdin)
- for {
- fmt.Print("Enter text: ")
- text, _ := reader.ReadString('\n')
- log.Print(text)
- pool.BroadcastMessage(text)
- }
- }()
- for {
- conn, err := listen.Accept()
- if err != nil {
- log.Fatalln(err)
- continue
- }
- go handler(conn, pool)
- }
- }
- func handler(conn net.Conn, pool *ClientPool) {
- client := pool.NewClient()
- defer pool.DeleteClient(client)
- defer conn.Close()
- defer log.Printf("Клиент с номером %d вышел\n", client.Id)
- log.Printf("Новый клиент присоединен, ему присвоен номер %d", client.Id)
- incomingClientMsg := make(chan string)
- exitSignal := make(chan bool)
- go func() {
- reader := bufio.NewReader(conn)
- for {
- text, err := reader.ReadString('\n')
- if err != nil {
- exitSignal <- true
- return
- }
- incomingClientMsg <- text
- }
- }()
- for {
- select {
- case <-exitSignal:
- return
- case text := <-incomingClientMsg:
- text = strings.Trim(text, "\r\n")
- if text == "/quit" {
- return
- }
- log.Printf("Клиент с номером %d написал: %s\n", client.Id, text)
- case text := <-client.MsgChan:
- _, err := conn.Write([]byte(text))
- if err != nil {
- return
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement