|
|
|
|
package net
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/gorilla/websocket"
|
|
|
|
|
"github.com/panjf2000/ants/v2"
|
|
|
|
|
"net"
|
|
|
|
|
"net/http"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Server TCP-Server
|
|
|
|
|
type Server struct {
|
|
|
|
|
// Name 服务端名称,默认为 n-net
|
|
|
|
|
Name string
|
|
|
|
|
// protocol 协议名
|
|
|
|
|
// "tcp", "tcp4", "tcp6", "unix" or "unixpacket"
|
|
|
|
|
// 若只想开启IPv4, 使用tcp4即可
|
|
|
|
|
protocol string
|
|
|
|
|
// address 服务地址
|
|
|
|
|
// 地址可直接使用hostname,但强烈不建议这样做,可能会同时监听多个本地IP
|
|
|
|
|
// 如果端口号不填或端口号为0,例如:"127.0.0.1:" 或 ":0",服务端将选择随机可用端口
|
|
|
|
|
address string
|
|
|
|
|
// 一些其它的东西 .etc..
|
|
|
|
|
handler *Handler
|
|
|
|
|
sessionMgr *SessionMgr
|
|
|
|
|
pool *ants.Pool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newServer(opts ...Option) *Server {
|
|
|
|
|
s := &Server{
|
|
|
|
|
Name: "",
|
|
|
|
|
protocol: "",
|
|
|
|
|
address: "",
|
|
|
|
|
handler: nil,
|
|
|
|
|
sessionMgr: nil,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
|
opt(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.pool, _ = ants.NewPool(0)
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) listenAndServe() {
|
|
|
|
|
listener, err := net.Listen(s.protocol, s.address)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 监听成功,服务已启动
|
|
|
|
|
// TODO log
|
|
|
|
|
defer listener.Close()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
conn, err := listener.Accept()
|
|
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, net.ErrClosed) {
|
|
|
|
|
// 服务端网络错误
|
|
|
|
|
// TODO print log
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// TODO log
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO 最大连接限制
|
|
|
|
|
//if s.ConnMgr.Len() >= utils.GlobalObject.MaxConn {
|
|
|
|
|
// conn.Close()
|
|
|
|
|
// continue
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
r := newRequest(s, conn)
|
|
|
|
|
|
|
|
|
|
s.pool.Submit(func() {
|
|
|
|
|
s.handler.handle(r)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) listenAndServeWS() {
|
|
|
|
|
upgrade := websocket.Upgrader{
|
|
|
|
|
ReadBufferSize: 1024,
|
|
|
|
|
WriteBufferSize: 1024,
|
|
|
|
|
CheckOrigin: nil,
|
|
|
|
|
EnableCompression: false,
|
|
|
|
|
}
|
|
|
|
|
http.HandleFunc(fmt.Sprintf("/%s/", "path"), func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
conn, err := upgrade.Upgrade(w, r, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// TODO upgrade failure, uri=r.requestURI err=err.Error()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// TODO s.handler.handleWS(conn)
|
|
|
|
|
})
|
|
|
|
|
if err := http.ListenAndServe(s.address, nil); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) listenAndServeWSTLS() {
|
|
|
|
|
upgrade := websocket.Upgrader{
|
|
|
|
|
ReadBufferSize: 1024,
|
|
|
|
|
WriteBufferSize: 1024,
|
|
|
|
|
CheckOrigin: nil,
|
|
|
|
|
EnableCompression: false,
|
|
|
|
|
}
|
|
|
|
|
http.HandleFunc(fmt.Sprintf("/%s/", "path"), func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
conn, err := upgrade.Upgrade(w, r, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// TODO upgrade failure, uri=r.requestURI err=err.Error()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// TODO s.handler.handleWS(conn)
|
|
|
|
|
})
|
|
|
|
|
if err := http.ListenAndServeTLS(s.address, "", "", nil); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|