码迷,mamicode.com
首页 > 其他好文 > 详细

go实现多聊天并发 服务端

时间:2019-10-02 21:09:29      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:def   net   发送   accept   write   协程   login   package   并发   

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实现多聊天并发 服务端

标签:def   net   发送   accept   write   协程   login   package   并发   

原文地址:https://www.cnblogs.com/paulversion/p/11618098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!