-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.go
138 lines (115 loc) · 2.48 KB
/
server.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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"fmt"
"io"
"net"
"runtime"
"sync"
"time"
)
// 创建一个server对象
type Server struct {
Ip string
Port int
// 在线用户的列表
OnlineMap map[string]*User
mapLock sync.RWMutex
// 消息广播的channle
Message chan string
}
// 创建一个Server 接口
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 (s *Server) Handler(conn net.Conn) {
fmt.Println("链接建立成功~~~")
user := NewUser(conn, s)
user.Online()
//监听用户是否活跃的channel
isLive := make(chan bool)
// 接收客户端发送的消息
go func() {
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
// 若读取的字节数为0,默认值
if n == 0 {
user.Offline()
return
}
if err != nil && err != io.EOF {
fmt.Println("Conn Read err:", err)
return
}
// 提取用户的消息(去除'\n')
msg := string(buf[:n-1])
// 用户针对msg进行消息处理
user.DoMessage(msg)
// 用户的任意消息,都代表当前用户时活跃的
isLive <- true
}
}()
// 查看OnlineMap
// fmt.Printf("%+v\n", s.OnlineMap)
// 当前handler阻塞
for {
select {
case <-isLive:
case <-time.After(time.Minute * 30):
// 已经超时,将当前的User强制关闭
user.SendMsg("你被踢了")
// 销毁channle资源
close(user.C)
// 关闭连接
conn.Close()
// 退出当前handler
// return
runtime.Goexit()
}
}
}
// 监听Message广播消息channle的goroutine,一旦有消息就发送给全部的在线User
func (s *Server) ListenMessage() {
for {
msg := <-s.Message
// 将msg发送给全部在在线的User
s.mapLock.Lock()
for _, m := range s.OnlineMap {
m.C <- msg
}
s.mapLock.Unlock()
}
}
// 广播消息的方法
func (s *Server) Broadcast(user *User, msg string) {
sendMsg := "[" + user.Addr + "]" + user.Name + ":" + msg
s.Message <- sendMsg
}
// 启动服务器接口
func (s *Server) Start() {
// socket listen
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.Ip, s.Port))
if err != nil {
fmt.Println("net.Listen err: ", err)
return
}
// 关闭监听程序
defer listener.Close()
// 启动监听广播的协程
go s.ListenMessage()
for {
// accept
conn, err2 := listener.Accept()
if err2 != nil {
fmt.Println("listener accept err: ", err2)
continue
}
go s.Handler(conn)
}
}