功能需求
- 实现单撩
- 实现群撩
- 实现用户上线的全网通知
- 实现用户昵称
- 实现聊天日志的存储和查看
服务端实现
type Client struct {
conn net.Conn
name string
addr string
}
var (
//客户端信息,用昵称为键
//clientsMap = make(map[string]net.Conn)
clientsMap = make(map[string]Client)
)
func SHandleError(err error, why string) {
if err != nil {
fmt.Println(why, err)
os.Exit(1)
}
}
func main() {
//建立服务端监听
listener, e := net.Listen("tcp", "127.0.0.1:8888")
SHandleError(e, "net.Listen")
defer func() {
for _, client := range clientsMap {
client.conn.Write([]byte("all:服务器进入维护状态,大家都洗洗睡吧!"))
}
listener.Close()
}()
for {
//循环接入所有女朋友
conn, e := listener.Accept()
SHandleError(e, "listener.Accept")
clientAddr := conn.RemoteAddr()
//TODO:接收并保存昵称
buffer := make([]byte, 1024)
var clientName string
for {
n, err := conn.Read(buffer)
SHandleError(err, "conn.Read(buffer)")
if n > 0 {
clientName = string(buffer[:n])
break
}
}
fmt.Println(clientName + "上线了")
//TODO:将每一个女朋友丢入map
client := Client{conn, clientName, clientAddr.String()}
clientsMap[clientName] = client
//TODO:给已经在线的用户发送上线通知——使用昵称
for _, client := range clientsMap {
client.conn.Write([]byte(clientName + "上线了"))
}
//在单独的协程中与每一个具体的女朋友聊天
go ioWithClient(client)
}
//设置优雅退出逻辑
}
//与一个Client做IO
func ioWithClient(client Client) {
//clientAddr := conn.RemoteAddr().String()
buffer := make([]byte, 1024)
for {
n, err := client.conn.Read(buffer)
if err != io.EOF {
SHandleError(err, "conn.Read")
}
if n > 0 {
msg := string(buffer[:n])
fmt.Printf("%s:%s\n