go聊天室

package main

import (
	"fmt"
	"net"
)
type client struct {
	name string
	addr string
	C    chan string
}

func writemsg2client(clinet client,conn net.Conn) {
	for m := range clinet.C {
		conn.Write([]byte(m + "\n"))
	}
}
func makemsg(name string, addr string, s string) string {
	return "[" + addr + "]" + name + " " +  s
}

//每一个进入聊天室的用户都将启动一个handleconn的go程来处理事件
func handleconn(conn net.Conn) {
	defer conn.Close()

	addr := conn.RemoteAddr().String()
	fmt.Printf("用户 %s 进入了房间\n", addr)
	client := client{addr, addr, make(chan string)}
	go writemsg2client(client,conn)

	onlinemap[addr] = client
	//登录进来一切准备就绪后就给所有人广播上线信息啦
	Message <- makemsg(client.name, addr, " 进入了房间")

	var ifquit=make(chan bool)
	//从这单独开启一个go程来读取用户输入的信息
	go func() {
		buf:=make([]byte,4096)
		for  {
			n,_:=conn.Read(buf)
			if n==0 {
				fmt.Printf("%s离开了房间\n",client.name)
				ifquit<-true
				return
			}

			Message<-makemsg(client.name,addr,string(buf[:n-1]))
		}
	}()
	for  {
		select {
		case <-ifquit:
			//退出处理
			delete(onlinemap,addr)
			Message<-makemsg(client.name,addr,"out time to leave")
			close(client.C)
			return
		}
	}
}

var Message = make(chan string)
var onlinemap map[string]client = make(map[string]client)
//主函数
func main() {
	listener, _ := net.Listen("tcp", "127.0.0.1:8888")
	defer listener.Close()
	//提前开启全局Message的go程,防止被阻塞
	go Manager()
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("accept err", err)
			continue
		}
		//每一个连接进来的用户都会被分配进入一个子go程,用来处理上面我们提到的各种功能
		go handleconn(conn)
	}
}

func Manager() {
	for {
		msg := <-Message
		fmt.Println(msg)
		for _, s := range onlinemap {
			s.C <- msg
		}
	}
}

  

https://blog.csdn.net/weixin_42940826/article/details/82386275

 

go聊天室

上一篇:Linux int型转换为char*型几种方法总结


下一篇:Linux实验 HBase的安装与使用