go語言易于實作高并發,簡易聊天室如下:
package main
import (
"fmt"
"net"
)
/*
主go程:創建監聽socket,for回圈accept獲取到客戶端的conn,開啟goroutine HandlerConnect
HandlerConnect:創建用戶結構體,存入onlineMap,發送用戶登錄廣播
Manager:監聽全域的channel message,將讀到的訊息廣播給onlineMap中的所有用戶
WriteMsgToClient:讀取每個用戶自帶channel C上訊息,回寫給用戶
*/
// 創建用戶結構體型別
type Client struct {
C chan string
Name string
Addr string
}
// 創建全域map,將用戶存盤到這里
var onlineMap map[string]Client
// 創建全域channel穿遞用戶訊息
var message = make(chan string)
func WriteMsgToClient(clnt Client, conn net.Conn) {
// 監聽用戶自帶Channel上是否有訊息
for msg := range clnt.C {
conn.Write([]byte(msg + "\n"))
}
}
func Manager() {
// 初始化map,onlineMap
onlineMap = make(map[string]Client)
for { // 回圈從message中讀取是否有資料
// 監聽channel中是否有資料,有資料存盤至message,無資料就阻塞
msg := <-message
// 回圈發送訊息給所有在線用戶
for _, clnt := range onlineMap {
clnt.C <- msg
}
}
}
func MakeMsg(clnt Client, msg string) (buf string) {
buf = "[" + clnt.Addr + "]" + clnt.Name + ":" + msg
return
}
func HandlerConnect(conn net.Conn) {
defer conn.Close()
// 獲取用戶網路地址
netAddr := conn.RemoteAddr().String()
// 創建新連接用戶的結構體
clnt := Client{make(chan string), netAddr, netAddr}
// 將新連接用戶添加到在線用戶map中,key:IP+port value:client
onlineMap[netAddr] = clnt
// 創建專門用來給當前用戶發送訊息的goroutine
go WriteMsgToClient(clnt, conn)
// 發送用戶上線訊息到全域通道中
//message <- "[" + netAddr + "]" + clnt.Name + "login"
message <- MakeMsg(clnt, "login")
// 創建一個匿名goroutine,專門處理用戶發送的訊息
go func() {
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if n == 0 {
fmt.Printf("檢測到客戶端%s退出\n", clnt.Name)
return
}
if err != nil {
fmt.Println("conn Read err", err)
return
}
// 將讀到的用戶訊息保存到msg中,string型別
msg := string(buf[:n])
// 將讀到的用戶訊息廣播給所用在線用戶(寫入到message中)
message <- MakeMsg(clnt, msg)
}
}()
// 保證不退出
for {
}
}
func main() {
// 創建監聽套接字
listener, err := net.Listen("tcp", "127.0.0.1:9001")
if err != nil {
fmt.Println("Listen err", err)
return
}
defer listener.Close()
// 創建管理者go程
go Manager()
// 回圈監聽客戶端請求
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("accept err", err)
return
}
go HandlerConnect(conn)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/282679.html
標籤:區塊鏈
上一篇:網路安全比賽理論答題(四)
