我尝试修改大猩猩聊天示例,以便向特定客户端发送消息而不是广播。首先,我将特定客户端存储在集线器中,以反对它的ID。
Hub.go
type Hub struct {
Clients map[int]*Client // Changed this piece to store id (int)
Broadcast chan []byte
Register chan *Client
Unregister chan *Client
}
func (h *Hub) Run() {
for {
select {
case client := <-h.Register:
fmt.Println("hub client register")
h.Clients[client.Id] = client
case client := <-h.Unregister:
fmt.Println("hub client Unregister")
fmt.Println(h.Clients[client.Id])
if h.Clients[client.Id] != nil {
delete(h.Clients, client.Id)
close(client.Send)
}
case message := <-h.Broadcast:
fmt.Println("to send to a specific client", string(message))
}
}
}
客户端
我已向客户添加了一个字段Id int,以了解哪个客户端已发送消息
type Client struct {
Hub *Hub
Conn *websocket.Conn
Send chan []byte
Id int // Id of the client,
}
func (c *Client) readPump() {
defer func() {
c.Hub.Unregister <- c
c.Conn.Close()
}()
c.Conn.SetReadLimit(maxMessageSize)
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
c.Conn.SetPongHandler(func(string) error { c.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
for {
_, message, err := c.Conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
log.Printf("error: %v", err)
}
break
}
message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
fmt.Println("client read message", string(message), "from", c.Id)
// {"to":512,"message":"Hi there."}
c.Hub.Broadcast <- message
}
}
为了能够将消息发送到特定客户端而不是广播,接下来需要采取哪些步骤。
消息本身来自客户端的JSON,指定&#39;到&#39;指示要发送的内容和要发送的消息。
{"to":512,"message":"Hi there."}
答案 0 :(得分:1)
定义代表消息的类型:
void sig_handler(int sig){
if(sig == SIGINT){
char res;
printf("\nAre you sure you want to terminate (Y/N)?\n");
kill(0, SIGTSTP); //envia sinal Stop ao processo pai
do{
read(STDIN_FILENO, &res, 1);
if (res == 'Y' || res == 'y')
{
kill(0,SIGTERM); //envia sinal de Terminacao ao proceso pai
}else
if (res == 'N' || res == 'n')
{
kill(0,SIGCONT); //envia sinal ao processo pai para continuar
break;
}
}while(res != 'Y' && res != 'y' && res != 'N' && res != 'n');
}
}
struct sigaction oldsigaction; //declarar antes de subscribe_SIGINT
void subscribe_SIGINT(){
sigaction(SIGTSTP, 0,&oldsigaction);
struct sigaction newsigaction;
newsigaction = oldsigaction;
newsigaction.sa_handler = &sig_handler;
sigaction(SIGTSTP, &newsigaction,0);
signal(SIGINT, sig_handler);
}
向Hub添加字段:
type Message struct {
id int
data []byte
}
并初始化频道以及集线器的其他频道。
将以下案例添加到集线器的选择中:
Send chan Message
在客户端的接收循环中,解析JSON以获取id和消息数据并将其发送到集线器:
case m := <-h.Send:
c, ok := clients[m.id]
if ok {
select {
case c.send <- m.data:
default:
delete(h.Clients, c.Id)
close(c.Send)
}
}