功能支持
|1.修改用户名————do
r
e
n
a
m
e
rename
rename"修改的用户名"
| 例如:修改用户名为java,do
r
e
n
a
m
e
rename
renamejava
|
|2.查看所有在线用户————do$list
|3.查看历史消息,最多支持查看10条
|4.用户上线提醒
全局变量,用于储存聊天历史记录
var MSGS []string
main.go文件
func main() {
port := "39003"
Listen, err := net.Listen("tcp", ":"+port)
if err != nil {
fmt.Println(err)
}
fmt.Println("Chatroom begin,listen port:", port)
connMap := make(map[net.Conn]string)
for {
conn, err := Listen.Accept()
defer conn.Close()
if err != nil {
fmt.Println(err.Error())
continue
}
connMap[conn] = conn.RemoteAddr().String()
//提醒用户上线
notice(conn)
//处理用户操作
go HandlerConn(conn, connMap)
}
}
处理每一个连接conn操作
func HandlerConn(conn net.Conn, connMap map[net.Conn]string) {
buf := make([]byte, 1024)
for {
n, err := conn.Read(buf)
if err != nil {
// fmt.Println("conn数据读取失败" + err.Error())
return
}
msg := strings.Trim(string(buf[:n]), "\r\n")
fmt.Printf("msg: %v\n", msg)
if strings.Contains(msg, "firstname") {
name := strings.ReplaceAll(msg, "firstname", "")
fisrtrename(conn, connMap, name)
broadcastUserOnline(conn, connMap, name+"用户上线")
fmt.Println(name + "用户上线")
continue
}
handlerMsg(conn, connMap, msg)
}
}
处理连接操作后,处理消息
消息操作,分为broadcast广播消息以及系统操作
当前支持操作,修改用户名,查看在线用户,查看历史聊天记录
func handlerMsg(conn net.Conn, connMap map[net.Conn]string, msg string) {
parseArr := strings.Split(msg, "$")
//判断消息是否为操作
if len(parseArr) > 1 && parseArr[0] == "do" {
//是——执行操作
switch parseArr[1] {
case "rename":
{
if len(parseArr) == 3 {
name := parseArr[2]
rename(conn, connMap, name)
} else {
returnerr(conn)
}
}
case "list":
{
if len(parseArr) == 2 {
list(conn, connMap)
}
}
case "hy":
{
if len(parseArr) == 2 {
getHistory(conn)
}
}
default:
{
returnerr(conn)
}
}
} else {
//否——广播信息
broadcast(conn, connMap, msg)
}
}
操作函数——获取聊天记录
func getHistory(conn net.Conn) {
allmsg := ""
for num, msg := range MSGS {
str := fmt.Sprintf("\n *******第%d条*******", num+1)
msg = str + msg
allmsg += msg
}
conn.Write([]byte(allmsg))
}
func save10Msg(msg string) {
MSGS = append(MSGS, msg)
// MSGS = MSGS[10:]
}
操作函数——获取在线列表
func list(conn net.Conn, connMap map[net.Conn]string) {
var listname string = ""
for connCur, name := range connMap {
_, err := connCur.Write([]byte("false"))
if err != nil {
delete(connMap, connCur)
continue
} else {
fmt.Printf("name: %v\n", name)
}
listname = listname + name + "\n"
}
conn.Write([]byte(listname))
}
操作函数——修改用户名
func rename(conn net.Conn, connMap map[net.Conn]string, name string) {
for connCur := range connMap {
if connCur == conn {
connMap[conn] = name
recmsg := "操作成功,修改name为:" + name + "\n"
conn.Write([]byte(recmsg))
}
}
}
广播消息操作
func broadcast(conn net.Conn, connMap map[net.Conn]string, msg string) {
for connCur := range connMap {
if conn == connCur {
up := "\n==========历史信息============\n"
msg := "time:" + time.Now().Format(" 15:04:05 ") + "\n" + "name:" + connMap[conn] + "\n" + "msg:" + msg + "\n"
down := "===========历史信息===========\n\n"
save10Msg(up + msg + down)
continue
}
up := "\n==========历史信息============\n"
msg := "time:" + time.Now().Format(" 15:04:05 ") + "\n" + "name:" + connMap[conn] + "\n" + "msg:" + msg + "\n"
down := "===========历史信息===========\n\n"
save10Msg(up + msg + down)
str := []byte(msg)
_, err := connCur.Write(str)
if err != nil {
// fmt.Println("broadcast fail", err.Error())
delete(connMap, connCur)
continue
}
}
}
其他函数①——提醒用户上线
func broadcastUserOnline(conn net.Conn, connMap map[net.Conn]string, msg string) {
for connCur := range connMap {
if conn == connCur {
continue
}
fmt.Println("回写内容")
str := []byte("time:" + time.Now().Format(" 15:04:05 ") + "\n" + "msg:" + msg + "\n")
_, err := connCur.Write(str)
if err != nil {
// fmt.Println("broadcast fail", err.Error())
delete(connMap, connCur)
continue
}
}
}
其他函数②——处理用户名的初始化
func fisrtrename(conn net.Conn, connMap map[net.Conn]string, name string) {
for connCur := range connMap {
if connCur == conn {
connMap[conn] = name
}
}
}
其他函数③——返回错误信息
func returnerr(conn net.Conn) {
errmsg := "参数错误,请重新输入\n"
conn.Write([]byte(errmsg))
}