刚来公司实习,每天都在划水,划水狗一只。自己写点东西,大家有意见可以直接留言。
功能:基于go语言和协程池,实现一个简单的聊天服务器。
服务器代码:
/*/////////////////////////////date:2018-3-17writer:fengzifunction:用go语言,基于一个可自增的协程池,实现多人聊天功能。函数首先创建协程池,然后根据用户连接,创建
多余的协程加入协程池,如果长时间未使用多余的协程,
系统自动回收多余协程。
/////////////////////////////*/import (
"fmt"
// "io"
"net"
)
var player map[net.Conn]int = map[net.Conn]int{} //存储用户连接
var message = make(chan net.Conn, 20) //用户连接的信道
var num int = 0 //连接的用户数量
var channelnum int = 0 //开辟的协程数量
var boolexit int = 0 //是否需要关闭多余协程
func main() {
socket, err := net.Listen("tcp", "localhost:8080")
if err != nil {
fmt.Println("net listen error:", err)
return
}defer socket.Close()
for i := 0; i < 2; i++ {
channelnum++go talkChannel()
}for {
conn, err := socket.Accept()
if err != nil {
continue
}message <- conn
//扩充协程池
if num >= 2 {
fmt.Println("get new channel", num)
channelnum++go talkChannel()
}//如果用户数量长时间小于现在的协程数量,那么关闭多余协程
if (channelnum >= 2) && (num < channelnum) {
boolexit++} else {
boolexit = 0
}fmt.Println("boolexit num:", boolexit)
//连续十次未用到多余协程,关闭多余协程
if boolexit > 10 {
message <- nil
boolexit = 0
}//go talk(conn)
}}
func talkChannel() {
for {
conn := <-message
//如果传递的是空,则关闭该协程
if conn == nil {
fmt.Println("close channel")
break
}fmt.Println("channel get one")
num++fmt.Println("talkchannel used:", num)
defer conn.Close()
player[conn] = 0
for {
buf := make([]byte, 128)
n, err := conn.Read(buf)
if err != nil {
delete(player, conn)
fmt.Println("one client close:", conn)
break
}buf = buf[0:n]
sendall(conn, buf)
} num-- }}
func talk(conn net.Conn) {
defer conn.Close()
player[conn] = 0
for {
buf := make([]byte, 8192)
n, err := conn.Read(buf)
if err != nil {
delete(player, conn)
fmt.Println("one client close:", conn)
break
}buf = buf[0:n]
fmt.Println(buf)sendall(conn, buf)
}}
//广播发送func sendall(conn net.Conn, buf []byte) {
for tmp, _ := range player {
if tmp != conn {
tmp.Write(buf) } }}
客户端:
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
socket, err := net.Dial("tcp", "localhost:8080")
if err != nil {
fmt.Println("net.dial error:", err)
return
}defer socket.Close()
go get(socket)
for {
var buff string
tmp := bufio.NewReader(os.Stdin)
buff, _ = tmp.ReadString('\n')
buff = buff[0 : len(buff)-2]
//fmt.Println(buff)
socket.Write([]byte(buff))
}}
func get(conn net.Conn) {
for {
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("socket link error:", err)
break
}buf = buf[0:n]
fmt.Println("others send:", string(buf))
}}
本文介绍了一个基于Go语言和协程池实现的简单多人聊天服务器。该服务器能够根据用户连接数动态调整协程池大小,并在用户活跃度降低时回收空闲协程。
4万+

被折叠的 条评论
为什么被折叠?



