go消息服务器吗,Go语言聊天服务器
本节将带领大家结合咱们前面所学的知识开发一个聊天的小程序,它可以在几个用户之间相互广播文本消息。这个程序里包含4个goroutine。主goroutine和广播(broadcaster)goroutine,每一个连接里面有一个连接处理(handleConn)goroutine和一个客户写入(clientwriter)goroutine。
广播器(broadcaster)是关于如何使用select的一个规范说明,因为它需要对三种不同的消息进行响应。
如下所示,主goroutine的工作是监听端口,接受连接客户端的网络连接。对每一个连接,它创建一个新的handleConngoroutine。
packagemainimport("bufio""fmt""log""net")funcmain(){listener,err:=net.Listen("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}gobroadcaster()for{conn,err:=listener.Accept()iferr!=nil{log.Print(err)continue}gohandleConn(conn)}}
下一个是广播器,它使用局部变量clients来记录当前连接的客户集合。每个客户唯一被记录的信息是其对外发送消息通道的ID,下面是细节:
typeclientchan
广播者监听两个全局的通道entering和leaving,通过它们通知客户的到来和离开,如果它从其中一个接收到事件,它将更新clients集合。如果客户离开,那么它关闭对应客户对外发送消息的通道。
广播者也监听来自messages通道的事件,所有的客户都将消息发送到这个通道。当广播者接收到其中一个事件时,它把消息广播给所有客户。
现在来看一下每个客户自己的goroutine。handleConn函数创建一个对外发送消息的新通道,然后通过entering通道通知广播者新客户到来。
接着,它读取客户发来的每一行文本,通过全局接收消息通道将每一行发送给广播者,发送时在每条消息前面加上发送者ID作为前缀。一旦从客户端读取完毕消息,handleConn通过leaving通道通知客户离开,然后关闭连接。
funchandleConn(connnet.Conn){ch:=make(chanstring)//对外发送客户消息的通道goclientWriter(conn,ch)who:=conn.RemoteAddr().String()ch
另外,handleConn函数还为每一个客户创建了写入(clientwriter)goroutine,它接收消息,广播到客户的发送消息通道中,然后将它们写到客户的网络连接中。客户写入者的循环在广播者收到leaving通知并且关闭客户的发送消息通道后终止。
下面的信息展示了同一个机器上的一个服务器和两个客户端,它们使用netcat程序来聊天:
$gobuildgopl.io/ch8/main
$gobuildgopl.io/ch8/netcat
$./main&
$./netcat
Youare127.0.0.1:64208 $./netcat
127.0.0.1:64211hasarrivedYouare127.0.0.1:64211
Hi!
127.0.0.1:64208:Hi! 127.0.0.1:64208:Hi!
Hiyourself.
127.0.0.1:64211:Hiyourself. 127.0.0.1:64211:Hiyourself.
^C
127.0.0.1:64208hasleft
$./netcat
Youare127.0.0.1:64216 127.0.0.1:64216hasarrived
Welcome.
127.0.0.1:64211:Welcome.127.0.0.1:64211:Welcome.
^C
127.0.0.1:64211hasleft
netcat的完整代码如下所示:
//netcat.go//netcat是一个简单的TCP服务器读/写客户端packagemainimport("io""log""net""os")funcmain(){conn,err:=net.Dial("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}done:=make(chanstruct{})gofunc(){io.Copy(os.Stdout,conn)//注意:忽略错误log.Println("done")done
当有n个客户session在连接的时候,程序并发运行着2n+2个相互通信的goroutine,它不需要隐式的加锁操作。clientsmap限制在广播器这一个goroutine中被访问,所以不会并发访问它。唯一被多个goroutine共享的变量是通道以及net.Conn的实例,它们又都是并发安全的。
总结
以上是生活随笔为你收集整理的go消息服务器吗,Go语言聊天服务器的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 如何让服务器运行js,服务器端JavaS
- 下一篇: 发起一个ajax请求,发送ajax请求