-
Notifications
You must be signed in to change notification settings - Fork 78
/
server.go
89 lines (79 loc) · 2.15 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
package main
import (
"flag"
"fmt"
"sync/atomic"
"github.com/panjf2000/gnet/v2"
"github.com/panjf2000/gnet/v2/pkg/logging"
"github.com/gnet-io/gnet-examples/simple_protocol/protocol"
)
type simpleServer struct {
gnet.BuiltinEventEngine
eng gnet.Engine
network string
addr string
multicore bool
connected int32
disconnected int32
}
func (s *simpleServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
logging.Infof("running server on %s with multi-core=%t",
fmt.Sprintf("%s://%s", s.network, s.addr), s.multicore)
s.eng = eng
return
}
func (s *simpleServer) OnOpen(c gnet.Conn) (out []byte, action gnet.Action) {
c.SetContext(new(protocol.SimpleCodec))
atomic.AddInt32(&s.connected, 1)
out = []byte("sweetness\r\n")
return
}
func (s *simpleServer) OnClose(c gnet.Conn, err error) (action gnet.Action) {
if err != nil {
logging.Infof("error occurred on connection=%s, %v\n", c.RemoteAddr().String(), err)
}
disconnected := atomic.AddInt32(&s.disconnected, 1)
connected := atomic.AddInt32(&s.connected, -1)
if connected == 0 {
logging.Infof("all %d connections are closed, shut it down", disconnected)
action = gnet.Shutdown
}
return
}
func (s *simpleServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
codec := c.Context().(*protocol.SimpleCodec)
var packets [][]byte
for {
data, err := codec.Decode(c)
if err == protocol.ErrIncompletePacket {
break
}
if err != nil {
logging.Errorf("invalid packet: %v", err)
return gnet.Close
}
packet, _ := codec.Encode(data)
packets = append(packets, packet)
}
if n := len(packets); n > 1 {
_, _ = c.Writev(packets)
} else if n == 1 {
_, _ = c.Write(packets[0])
}
return
}
func main() {
var port int
var multicore bool
// Example command: go run server.go --port 9000 --multicore=true
flag.IntVar(&port, "port", 9000, "--port 9000")
flag.BoolVar(&multicore, "multicore", false, "--multicore=true")
flag.Parse()
ss := &simpleServer{
network: "tcp",
addr: fmt.Sprintf(":%d", port),
multicore: multicore,
}
err := gnet.Run(ss, ss.network+"://"+ss.addr, gnet.WithMulticore(multicore))
logging.Infof("server exits with error: %v", err)
}