go实现多聊天并发 服务端
Posted paulversion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go实现多聊天并发 服务端相关的知识,希望对你有一定的参考价值。
package main
import (
"fmt"
"net"
"time"
)
type Client struct
ch chan string //用户发送数据的管道
name string //用户名
addr string//网络地址
var message = make(chan string) //用来保存用户的消息
//定义一个map 值为在线的用户
var onlineClientMap map[string]Client//
func main()
listener,err := net.Listen("tcp","127.0.0.1:8000")
if err !=nil
fmt.Println(err)
defer listener.Close()
go Manager()
//主协程,循环阻塞用户连接
for
conn, err := listener.Accept()
if err!=nil
fmt.Println(err)
continue
go handleConn(conn)
func makeMsg(client Client,msg string)(buff string)
buff ="["+client.addr+"]"+client.name+":"+msg+"\n"
return
func handleConn(conn net.Conn)
cliAddr:= conn.RemoteAddr().String()
defer conn.Close()
client :=Client
make(chan string),
cliAddr,
cliAddr,
onlineClientMap[cliAddr] = client
//给当前客户端发送信息
go writeMsgToClient(client,conn)
//广播某个在线
message<-"I am here\n"
message<- makeMsg(client,"login")
//是否主动退出
isQuit:=make(chan bool)
hasData:= make(chan bool)
//新开一个协程接收用户发过来的数据
go func()
buff:= make([]byte,2048)
for
n,err :=conn.Read(buff)
fmt.Println(n)
if err!=nil
fmt.Println(nil)
if n==0
fmt.Println("断开连接")
isQuit<-true
return
msg := string(buff[:n-1])
if len(msg)==3&& msg =="who"
for _,tmp := range onlineClientMap
msg = tmp.addr+":"+tmp.name+"\n"
conn.Write([]byte(msg))
else
message<-makeMsg(client,msg)
hasData<-true
()
for
select
case <-isQuit:
delete(onlineClientMap,cliAddr)//当前用户从map移除
message<-makeMsg(client,"login out")//广播退出
return
case <-hasData:
case <-time.After(60*time.Second):
delete(onlineClientMap,cliAddr)//当前用户从map移除
message<-makeMsg(client,"time out")//广播退出
return
func Manager()
onlineClientMap = make(map[string]Client)//给map分配空间
for
msg := <-message
for _ ,client :=range onlineClientMap
client.ch<-msg
func writeMsgToClient(client Client,conn net.Conn)
for msg:= range client.ch
conn.Write([]byte(msg))
以上是关于go实现多聊天并发 服务端的主要内容,如果未能解决你的问题,请参考以下文章