Вот пример с пулом клиентов и сохранением в map.
Клиентам рассылается то, что набрано на сервере, данные, пришедшие от клиентов обрабатываются.
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)
go func() {
reader := bufio.NewReader(conn)
for {
text, err := reader.ReadString('\n')
if err != nil {
close(incomingClientMsg)
return
}
incomingClientMsg <- text
}
}()
for {
select {
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
}
}
}
}