Answer the question
In order to leave comments, you need to log in
How to send data to all routines?
Thanks to FireGM for helping me fix sending messages from the terminal to clients. In theory, the code should send data to all clients. Now I have connected two clients, I write the first message, it comes only to the first client, I write the second message, it comes only to the second client, I write the third SMS, it comes only to the first, etc.
Server Code
package main
import (
"bufio"
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"strings"
)
var messages chan string
func main() {
messages = make(chan string, 10)
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)
messages <- text
}
}()
for {
conn, err := listen.Accept()
if err != nil {
log.Fatalln(err)
continue
}
go handler(conn)
}
}
func handler(conn net.Conn) {
defer conn.Close()
var (
buf = make([]byte, 1024)
r = bufio.NewReader(conn)
w = bufio.NewWriter(conn)
)
ILOOP:
for {
n, err := r.Read(buf)
data := string(buf[:n])
switch err {
case io.EOF:
break ILOOP
case nil:
//log.Println("Получил:", data)
if isTransportOver(data) {
break ILOOP
}
default:
log.Fatalf("Ошибка при получении:%s", err)
return
}
}
//данные из канала
msg := <-messages
w.Write([]byte(msg))
w.Flush()
}
func isTransportOver(data string) (over bool) {
over = strings.HasSuffix(data, "\r\n\r\n")
return
}
Answer the question
In order to leave comments, you need to log in
https://gist.github.com/drewolson/3950226 here is a good example of implementing a pool of clients. Just cut out the excess and you'll be fine.
remade that example, with the removal of dead connectors when sending. I cut out a little, it only works for sending to the client.
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
type Client struct {
writer *bufio.Writer
}
func (client *Client) Write(data string) error {
fmt.Println("client write")
_, err := client.writer.WriteString(data)
err = client.writer.Flush()
return err
}
func NewClient(connection net.Conn) *Client {
writer := bufio.NewWriter(connection)
client := &Client{
writer: writer,
}
return client
}
type ChatRoom struct {
clients []*Client
}
func (chatRoom *ChatRoom) Broadcast(data string) {
deleted := 0
for i := range chatRoom.clients {
j := i - deleted
if err := chatRoom.clients[j].Write(data); err != nil {
fmt.Println(err, "deleted error")
chatRoom.clients = chatRoom.clients[:j+copy(chatRoom.clients[j:], chatRoom.clients[j+1:])]
deleted++
}
}
}
func (chatRoom *ChatRoom) Join(connection net.Conn) {
client := NewClient(connection)
chatRoom.clients = append(chatRoom.clients, client)
}
func NewChatRoom() *ChatRoom {
chatRoom := &ChatRoom{
clients: make([]*Client, 0),
}
return chatRoom
}
func main() {
chatRoom := NewChatRoom()
listener, _ := net.Listen("tcp4", ":3333")
go readAndSend(chatRoom)
for {
conn, err := listener.Accept()
if err != nil {
continue
}
chatRoom.Join(conn)
}
}
func readAndSend(chatRoom *ChatRoom) {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
log.Print(text)
chatRoom.Broadcast(text)
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question