承认吧,你肯定也会有深夜寂寞时特别想找人聊天但翻遍朋友圈,却还是没有发现合适的人的时候,今天我们就来写一个随机配对聊天程序,解决广大单身狗寂寞时想要找人聊天的需求吧。
为了让聊天不那么 gay
,我们的聊天程序会让异性匹配聊天,用户通过客户端连接到聊天程序服务器 localhost:8080
,例如使用 netcat
通过 nc localhost 8080
命令连接聊天程序服务器,服务器会根据你的性别匹配异性聊天。
在实现方面,为了达到异性相互聊天的目标,我们创建两个通道,分别是 boy
通道和 girl
通道,并通过 net.Listen
方法监听 8080
端口,对于每个连接我们起一个 goroutine
进行匹配操作。
1 | var boy = make(chan io.ReadWriteCloser) |
match
方法会首先询问你的性别,如果是男生则匹配女生聊天,反之亦然。如果当前只有一个男生连进来,程序会执行第一个 select
中的 case boy <- c:
条件,由于 boy
通道是 unbuffered channel
,直到有女生进来之前该操作都会阻塞。如果此时进来一个女生,程序会执行第二个select
操作,由于 girl
通道也是 unbuffered channel
,所以case girl <- c:
语句也会阻塞,但此时 case p := <-boy:
会被执行,这时候就可以通过 chat
方法让两个 net.Conn
相互交流了。match
方法实现的逻辑就达到了异性交流的目的了。
1 | func match(c io.ReadWriteCloser) { |
上面的 chat
方法依赖 cp
方法 ,该方法封装了 io.Copy
方法,主要就是为了当任意一方结束聊天时发送一个 err
到我们的 errc
,以关闭双方的连接。
1 | func cp(w io.Writer, r io.Reader, errc chan<- error) { |
chat
方法通过两个 goroutine
,go cp(a, b, errc)
和 go cp(b, a, errc)
使a和b这两个 net.Conn
相互发送消息,如果任意一方结束聊天, errc
通道就会返回一个 error
值,a和b就会被关闭,此时聊天结束。
1 | func chat(a, b io.ReadWriteCloser) { |