上文Go websocket 聊天室demo以及k8s 部署 后面有一个问题, 如果2个客服端 分别来链接到不同的服务 如何发布消息了?
如图:
cliant A ->ServerA ----推送消息到kafka---->推送消息到 服务A和B---->服务AB都去寻找自己的client集合------>发送消息给具体的客户端【有可能是广播 也可能是指定具体的用户】
代码:
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"time"
"github.com/Shopify/sarama"
"github.com/gorilla/websocket"
uuid "github.com/satori/go.uuid"
)
//客户端管理
type ClientManager struct {
//客户端 map 储存并管理所有的长连接client,在线的为true,不在的为false
clients map[string]*Client
//web端发送来的的message我们用broadcast来接收,并最后分发给所有的client
broadcast chan []byte
//新创建的长连接client
register chan *Client
//新注销的长连接client
unregister chan *Client
}
//客户端 Client
type Client struct {
//用户id
id string
//连接的socket
socket *websocket.Conn
//发送的消息
send chan []byte
//服务器IP
ip string
}
//会把Message格式化成json
type Message struct {
//消息struct
Sender string `json:"sender,omitempty"` //发送者
Recipient string `json:"recipient,omitempty"` //接收者
Content string `json:"content,omitempty"` //内容
}
//创建客户端管理者
var manager = ClientManager{
broadcast: make(chan []byte),
register: make(chan *Client),
unregister: make(chan *Client),
clients: make(map[string]*Client),
}
func (manager *ClientManager) start() {
for {
select {
case conn := <-manager.register:
manager.clients[conn.id] = conn
//把返回连接成功的消息json格式化
jsonMessage, _ := json.Marshal(&Message{Content: "/A new socket has connected. " + conn.ip, Sender: conn.id})
//manager.send(jsonMessage)
syncProducer(jsonMessage)
//如果连接断开了
case conn := <-manager.unregister:
//判断连接的状态,如果是true,就关闭send,删除连接client的值
if _, ok := manager.clients[conn.id]; ok {
close(conn.send)
delete(manager.clients, conn.id)
jsonMessage, _ := json.Marshal(&Messag