加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
chatRoom.go 2.78 KB
一键复制 编辑 原始数据 按行查看 历史
HURUIZHE 提交于 2022-03-04 05:08 . 上传代码
package main
import (
"fmt"
"log"
"net"
"strings"
"time"
)
type Client struct {
C chan string
Name string
Addr string
}
//创建全局map,存储在线用户
var onlineMap map[string]Client
//创建全局channel,传递用户信息
var message = make(chan string)
func WriteMsgToClient(clnt Client, conn net.Conn) {
for msg := range clnt.C {
conn.Write([]byte(msg + "\n"))
}
}
func MakeMsg(clnt Client, msg string) string {
buf := "[" + clnt.Addr + "]" + clnt.Name + ":" + msg
return buf
}
func HandlerConnect(conn net.Conn) {
defer conn.Close()
netAddr := conn.RemoteAddr().String()
clnt := Client{make(chan string), netAddr, netAddr}
//添加到map
onlineMap[netAddr] = clnt
//创建channel检查用户是否活跃
hasData := make(chan bool)
//创建专门给当前用户发送消息的goroutine
go WriteMsgToClient(clnt, conn)
//发送上线消息到全局channel
message <- MakeMsg(clnt, "login")
//创建一个channel,用来判断退出状态
isQuit := make(chan bool)
go func() {
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if n == 0 {
isQuit <- true
fmt.Printf("检测到客户端:%s退出\n", clnt.Name)
return
}
if err != nil {
log.Println("conn.Read出错", err)
return
}
msg := string(buf[:n])
if len(msg) == 3 && msg == "who" {
conn.Write([]byte("online user list:\n"))
for _, user := range onlineMap {
userInfo := user.Addr + ":" + user.Name + "\n"
conn.Write([]byte(userInfo))
}
} else if len(msg) > 7 && msg[:6] == "rename" {
newName := msg[7:]
clnt.Name = newName
onlineMap[netAddr] = clnt
conn.Write([]byte("rename successfully\n"))
} else if len(msg) > 2 && msg[:2] == "To" {
tmp := strings.Split(msg, ":")
name := tmp[0][3:]
for _, j := range onlineMap {
if j.Name == name {
j.C <- tmp[1]
}
}
} else {
message <- MakeMsg(clnt, msg)
}
hasData <- true
}
}()
for {
select {
case <-isQuit:
delete(onlineMap, netAddr)
message <- MakeMsg(clnt, "logout")
return
case <-hasData:
//重置计时器
case <-time.After(time.Second * 60):
delete(onlineMap, netAddr)
message <- MakeMsg(clnt, "logout")
return
}
}
}
func Manager() {
//初始化map和message
onlineMap = make(map[string]Client)
for {
//循环监听message
msg := <-message
//循环发送消息给在线用户
for _, clnt := range onlineMap {
clnt.C <- msg
}
}
}
func main() {
//创建监听套接字
listener, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {
log.Println("Listen err", err)
return
}
defer listener.Close()
go Manager()
//循环监听客户端连接请求
for {
conn, err := listener.Accept()
if err != nil {
log.Println("Accept err", err)
return
}
go HandlerConnect(conn)
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化