package main import ( "fmt" "net" "strings" ) type User struct { Name string Addr string C chan string conn net.Conn server *Server // 当前客户端所属的Server } // 创建一个User的API func NewUser(conn net.Conn, server *Server) *User { userAddr := conn.RemoteAddr().String() user := &User{ Name: userAddr, Addr: userAddr, C: make(chan string), conn: conn, server: server, } // 启动监听当前user channel的goroutine go user.ListenMessage() return user } // User类的成员方法:用户上线处理 func (user *User) Online() { // 用户上线,将用户加入到server的OnlineMap中 user.server.mapLock.Lock() user.server.OnlineMap[user.Name] = user user.server.mapLock.Unlock() // 广播当前用户上线消息 user.server.BroadCast(user, "已上线") } // User类的成员方法:用户下线处理 func (user *User) Offline() { // 用户下线,将用户从server的OnlineMap中删除 user.server.mapLock.Lock() delete(user.server.OnlineMap, user.Name) user.server.mapLock.Unlock() // 广播当前用户下线消息 user.server.BroadCast(user, "下线了") } func (user *User) SendMsg(msg string) { user.conn.Write([]byte(msg)) } // User类的成员方法:处理用户消息 func (user *User) DoMessage(msg string) { if msg == "who" { // 约定查询在线用户指令who user.server.mapLock.Lock() for _, onlineuser := range user.server.OnlineMap { onlineMsg := fmt.Sprintf("[%s]%s:在线\n", onlineuser.Addr, onlineuser.Name) // 只向当前这个user发送消息 user.SendMsg(onlineMsg) } user.server.mapLock.Unlock() } else if len(msg) > 7 && msg[:7] == "rename|" { // 约定rename|xx指令为定义我的用户名指令 newName := strings.Split(msg, "|")[1] // 查询newName在当前在线列表中是否已经存在 _, ok := user.server.OnlineMap[newName] if ok { user.SendMsg(fmt.Sprintf("用户名%s已被占用\n", newName)) } else { user.server.mapLock.Lock() delete(user.server.OnlineMap, user.Name) user.server.OnlineMap[newName] = user user.server.mapLock.Unlock() // 向大家广播一下新名字 user.server.BroadCast(user, fmt.Sprintf("修改了用户名为%s\n", newName)) user.Name = newName // 自本人反馈一下改名成功 user.SendMsg(fmt.Sprintf("你已经修改用户名为%s\n", user.Name)) } } else if len(msg) > 4 && msg[:3] == "to|" { // 私聊消息格式:to|name|content if len(strings.Split(msg, "|")) != 3 { user.SendMsg("私聊消息格式不正确,请使用\"to|name|content\"格式。\n") return } // 获取对方的用户名 remoteName := strings.Split(msg, "|")[1] if remoteName == "" { user.SendMsg("私聊消息格式不正确,请使用\"to|name|content\"格式。\n") return } // 根据用户名得到对方User对象 remoteUser, ok := user.server.OnlineMap[remoteName] if !ok { user.SendMsg("用户" + remoteName + "不存在\n") return } // 获取消息内容,通过对方的User对象将消息内容发送过去 content := strings.Split(msg, "|")[2] if content == "" { user.SendMsg("无消息内容,请重发\n") return } remoteUser.SendMsg(user.Name + "对你说:" + content + "\n") } else { user.server.BroadCast(user, msg) } } // User类的成员方法: 监听消息 func (user *User) ListenMessage() { for { msg := <-user.C user.conn.Write([]byte(msg + "\n")) } }