go 及时通信-用户业务封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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)
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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)
    }
}

  

posted @   柠檬树下少年蓝  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示