代码拉取完成,页面将自动刷新
package zzserver
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"time"
//"gitee.com/douyaye/zzserver/zztools"
"log"
"net/http"
"os"
"os/signal"
)
// Server maintains the set of active clients and broadcasts messages to the
// clients.
type Server struct {
router IRouter
//监听的端口
WsPort int
TcpPort int
connected chan *Client //刚进入的,放入管道
disconnected chan *Client //退出的,放入管道
clients map[int]*Client // [登陆序号]客户端
onlineNumber int //在线人数
broadcast chan []byte //广播消息
ConnectionIndex int64 //连接计数
chanRange chan func(c *Client) bool //
GinEng *gin.Engine
}
//ZZServer 单例
//var ZZServer *Server
func NewZZServer() *Server {
s := &Server{
clients: make(map[int]*Client),
broadcast: make(chan []byte, 64),
connected: make(chan *Client, 64),
disconnected: make(chan *Client, 64),
chanRange: make(chan func(c *Client) bool, 64),
}
go s.run()
return s
}
//func init() {
// ZZServer = &Server{
// broadcast: make(chan []byte, 64),
// login: make(chan *Client, 64),
// connected: make(chan *Client, 64),
// disconnected: make(chan *Client, 64),
// ClientsNotloggedin: make(map[int]*Client),
// }
// go ZZServer.run()
//
// InitLogs()
//}
// run 开始
func (h *Server) run() {
defer func() {
panic("hub run 方法运行终止 , 程序结束退出!")
}()
for {
select {
case client := <-h.connected: //用户连接
h.clients[client.ConnectionIndex] = client
//log.Println("用户 进入:"+client.GetRemoteAddr()+",当前登录:", h.ClientsNum, ",未登录:", len(h.ClientsNotloggedin))
h.onlineNumber++
case client := <-h.disconnected: //用户断开连接
client.Close()
if _, ok := h.clients[client.ConnectionIndex]; ok {
delete(h.clients, client.ConnectionIndex)
h.onlineNumber--
}
// log.Println("当前人数:", h.ClientsNum)
// log.Print("用户 断开:"+client.GetRemoteAddr()+",当前登录:", len(h.clients), "未登录:", len(h.ClientsNotloggedin), "\r\n")
case message := <-h.broadcast: //广播消息
//var socketMsg = packet(message) //socket先封装, 再发送
for _, client := range h.clients {
//client.sendByteWithNoPacket(message, socketMsg)
client.SendByte(message)
}
case f := <-h.chanRange:
for _, client := range h.clients {
if !f(client) {
break
}
}
}
}
}
func (h *Server) SetRouter(r IRouter) {
h.router = r
}
//SendToAll 广播消息
func (h *Server) SendToAll(message []byte) {
h.broadcast <- message
}
//SendToAllJson 广播消息
func (h *Server) SendToAllJson(obj interface{}) {
b, err := json.Marshal(obj)
if err != nil {
return
}
h.broadcast <- b
}
// startTcpSocket 开启socket监听
func (h *Server) startTcpSocket() {
//开启普通socket监听
serverSocket(h, fmt.Sprintf(":%d", h.TcpPort))
}
// startWebsocketAndHttp 开启websocket和http监听
func (h *Server) startWebsocketAndHttp() {
//开启普通websocket监听
defer func() {
log.Fatalln("websocket监听 已经退出!")
}()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
return
}
serveWs(h, w, r)
})
err := http.ListenAndServe(fmt.Sprintf(":%d", h.WsPort), nil)
if err != nil {
log.Fatal(err)
}
//var err error
//if !zzcfg.Wss {
// err = http.ListenAndServe(websocketaddr, nil)
//} else {
// //err := http.ListenAndServeTLS(":443", "server.crt", "server.pem", nil)
// log.Println("server run WSS")
// err = http.ListenAndServeTLS(websocketaddr, zzcfg.Wss_cert, zzcfg.Wss_key, nil)
//}
}
func (h *Server) startGinWebsocket() {
//g := gin.Default()
//g.Any("/", h.serveWsGin)
if h.GinEng == nil {
gin.SetMode("release")
h.GinEng = gin.New()
h.GinEng.Use(gin.Recovery())
log.Println("use default gin")
}
h.GinEng.GET("/", func(c *gin.Context) {
if c.Request.URL.Path != "/" {
return
}
startWs(h, c.Writer, c.Request)
})
err := h.GinEng.Run(fmt.Sprintf(":%d", h.WsPort))
if err != nil {
log.Fatal(err)
return
}
}
//func (h *Server) hello(c *gin.Context) {
// c.String(http.StatusOK, "hello to you too")
// //log.Println("test: hello")
//}
func (h *Server) Start() {
if h.router == nil {
log.Fatalln("please set router use server.SetRouter()")
return
}
//defer func() {
// h.Close()
// time.Sleep(time.Second)
//}()
//log.SetFlags(log.Lshortfile | log.LstdFlags)
//zztools.PrintServerIps()
if h.WsPort > 0 {
log.Println("Websocket 启动成功! ", h.WsPort)
//go h.startWebsocketAndHttp() //开启普通websocket监听
go h.startGinWebsocket() //开启普通websocket监听
}
if h.TcpPort > 0 {
fmt.Println("TCP 启动成功", h.TcpPort)
go h.startTcpSocket()
}
//log.Println("zzServer start success")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
s := <-c
log.Println("Got signal", s, "程序执行结束 执行Close()")
h.Close()
time.Sleep(time.Second)
log.Println("服务器关闭, 再见~ ")
}
func (h *Server) Close() {
if h.router != nil {
h.router.OnServerClose()
}
}
func (h *Server) Online() int {
return h.onlineNumber
}
//Range 在同一个go中执行, 不要执行很久的操作
func (h *Server) Range(f func(c *Client) bool) {
select {
case h.chanRange <- f:
default:
log.Println("(h *Server) Range ERROR: chan is full")
//return errors.New("chan is full")
}
}
//关闭服务器
func closeserver() {
//ZZServer.IsClosing = true
//router.OnServerClose()
//log.Println("服务端 等待数据库队列完成!!")
//time.Sleep(1 * time.Second)
//zzdbhelp.Workor_end()
//ZZServer.wg_dbwork.Wait() //等待数据库执行完成
//log.Println("服务端 执行完毕退出!!")
//os.Exit(0)
}
//func (h *Server) WaiteToClose() {
// log.Println("WaiteToClose 等待程序执行完毕后退出")
// if ZZServer.CanCloseImmediatelyGame {
// ZZServer.NeedClose = true
// ZZServer.Wg_Close.Done()
// } else {
// ZZServer.NeedClose = true
// }
//}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。