栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang完成聊天室功能

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang完成聊天室功能

go语言易于实现高并发,简易聊天室如下:

package main

import (
	"fmt"
	"net"
)


// 创建用户结构体类型
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)
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/909425.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号