即时通信系统版本预览:
- 版本一:构建基础server
- 版本二:用户上线功能
- 版本三:用户消息广播机制
- 版本四:用户业务层封装
- 版本五:在线用户查询
- 版本六:修改用户名
- 版本七:超时强踢功能
- 版本八:私聊功能
- 版本九:客户端实现
版本二:用户上线功能并向所有用户广播
user.go
- 定义user对象
type User struct {
Name string
Addr string
C chan string
conn net.Conn
}
- 创建user对象
func NewUser(conn net.Conn) *User{
userAddr := conn.RemoteAddr().String()
user := &User{
Name: userAddr,
Addr: userAddr,
C: make(chan string),
conn: conn,
}
go user.ListenMessage()
return user
}
- 监听user对应的channel消息
func (this *User) ListenMessage() {
for{
msg := <- this.C
this.conn.Write([]byte(msg + "\n"))
}
}
server.go
- 添加server对象属性
type Server struct {
Ip string
Port int
OnlineMap map[string]*User
mapLock sync.RWMutex
Message chan string
}
- 创建server对象
func NewServer(ip string, port int) *Server {
server := &Server{
Ip: ip,
Port: port,
OnlineMap:make(map[string]*User),
Message:make(chan string),
}
return server
}
- 用户连接上,就进入了handler方法
func (this *Server) Handler(conn net.Conn) {
fmt.Println("链接建立成功",conn)
user := NewUser(conn)
this.mapLock.Lock()
this.OnlineMap[user.Name] = user
this.mapLock.Unlock()
this.BroadCats(user, "已上线")
select {
}
}
- 创建广播BroadCats方法
func (this *Server) BroadCats(user *User, msg string) {
sendMsg := "[" + user.Addr + "]" + user.Name + ":" + msg
this.Message <- sendMsg
}
- 创建向所有user发送广播消息的方法
func (this *Server) ListenMessage() {
for {
msg := <-this.Message
this.mapLock.Lock()
for _, cli := range this.OnlineMap {
cli.C <- msg
}
this.mapLock.Unlock()
}
}