package main
import "net"
//构件用户对象
type User struct {
Name string
Addr string
C chan string
Conn net.Conn
Server *Server
}
//用户API
func NewUser(conn net.Conn, server *Server) *User {
//用户地址
userAddr := conn.RemoteAddr().String()
user := &User{
Name: userAddr,
Addr: userAddr,
C: make(chan string),
Conn: conn,
Server: server,
}
//启动go程
go user.ListMessage()
return user
}
//监听channel信息
func (this *User) ListMessage() {
for {
msg := <-this.C
this.Conn.Write([]byte(msg + "\n"))
}
}
//上线业务
func (this *User) OnLine() {
//用户上线
this.Server.MapLock.Lock()
this.Server.OnlineMap[this.Addr] = this
this.Server.MapLock.Unlock()
//发送消息
this.Server.BroadCast(this, "shangxianle")
}
//下线业务
func (this *User) OffLine() {
this.Server.MapLock.Lock()
delete(this.Server.OnlineMap, this.Addr)
this.Server.MapLock.Unlock()
//用户下线
this.Server.BroadCast(this, "xianxianle")
}
//消息业务
func (this *User) DoMessage(msg string) {
this.Server.BroadCast(this, msg)
}
package main
import (
"fmt"
"io"
"net"
"sync"
)
//构件server
type Server struct {
Ip string
Port int
//在线用户列表
OnlineMap map[string]*User
MapLock sync.RWMutex
//消息
Message chan string
}
//提供一个对外的接口
func NewServer(ip string, port int) *Server {
server := &Server{
Ip: ip,
Port: port,
OnlineMap: make(map[string]*User),
Message: make(chan string),
}
return server
}
//发送消息
func (this *Server) BroadCast(user *User, msg string) {
sendMsg := "[" + user.Addr + "]" + ":" + msg
this.Message <- sendMsg
}
func (this *Server) Handler(conn net.Conn) {
// fmt.Println("链接成功")
user := NewUser(conn, this)
//用户上线
user.OnLine()
//接收客户端消息并发送
go func() {
buf := make([]byte, 5000)
for {
//读取输入
n, err := conn.Read(buf)
if n == 0 {
//用户下线
user.OffLine()
return
}
if err != nil && err != io.EOF {
fmt.Println("conn read err:", err)
return
}
msg := string(buf[:n-1])
//用户针对消息处理
user.DoMessage(msg)
}
}()
//阻塞
select {}
}
//监听channel
func (this *Server) ListMessager() {
for {
msg := <-this.Message
//发送每个用户channel
this.MapLock.Lock()
for _, cli := range this.OnlineMap {
cli.C <- msg
}
this.MapLock.Unlock()
}
}
//启动
func (this *Server) start() {
//监听客户端
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", this.Ip, this.Port))
if err != nil {
fmt.Println("listener err:", err)
return
}
//关闭
defer listener.Close()
go this.ListMessager()
for {
//连接
conn, err := listener.Accept()
if err != nil {
fmt.Println("conn err:", err)
continue
}
//启动go handler操作
go this.Handler(conn)
}
}