package network
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/togettoyou/wsc"
owlconfig "github.com/xssed/owlcache/config"
"github.com/xssed/owlcache/group"
owllog "github.com/xssed/owlcache/log"
"github.com/xssed/owlcache/network/websocketclient"
owltools "github.com/xssed/owlcache/tools"
"github.com/xssed/owlcache/tools/timeout"
)
var WSClist *websocketclient.WSCList
func startWebSocketClient() {
WSClist = websocketclient.NewWSCList()
list := ServerGroupList.Values()
for k := range list {
val, ok := list[k].(group.OwlServerGroupRequest)
if ok {
go WebSocketClientConnToServer(val.Address)
}
}
}
func WebSocketClientConnToServer(address string) {
done := make(chan bool)
ws := websocketclient.NewWebSocketClient(address)
ws.OnConnected(func() {
WSClist.AddActiveWSC(ws)
owllog.OwlLogWebsocketClient.Info(owltools.JoinString("WebSocketClient: Connect to server(OnConnected): ", ws.WebSocket.Url))
})
ws.OnConnectError(func(err error) {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnConnectError: ", err.Error()))
})
ws.OnDisconnected(func(err error) {
WSClist.RemoveDieWSC(ws)
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnDisconnected: ", err.Error()))
})
ws.OnTextMessageSent(func(message string) {
})
ws.OnBinaryMessageSent(func(data []byte) {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnBinaryMessageSent: ", string(data)))
})
ws.OnSentError(func(err error) {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnSentError: ", err.Error()))
})
ws.OnPingReceived(func(appData string) {
})
ws.OnPongReceived(func(appData string) {
})
ws.OnTextMessageReceived(func(message string) {
OwlResponseToWSCGroupCache(message, JsonStrToOwlResponse(message))
})
ws.OnBinaryMessageReceived(func(data []byte) {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnBinaryMessageReceived: ", string(data)))
})
go ws.Connect()
ws.OnClose(func(code int, text string) {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnClose: ", strconv.Itoa(code), text))
WSClist.RemoveDieWSC(ws)
done <- true
})
for {
select {
case <-done:
return
}
}
}
func test() {
go func() {
t := time.NewTicker(5 * time.Second)
for {
select {
case <-t.C:
fmt.Println(WSClist.GetList())
for _, ws := range WSClist.GetList() {
err := ws.SendTextMessage("get hello data")
if err == wsc.CloseErr {
return
}
}
}
}
}()
}
func (owlhandler *OwlHandler) GetWCGroupData(w http.ResponseWriter, r *http.Request) {
resmap := owlhandler.conversionContentInfo(owlhandler.getWSCData())
if string(owlhandler.owlrequest.Value) != "info" {
if len(resmap) == 0 {
owlhandler.Transmit(NOT_FOUND)
owlhandler.owlresponse.Data = []byte("")
return
}
owlhandler.Transmit(SUCCESS)
owlhandler.owlresponse.Data = resmap[0]["Data"].([]byte)
return
}
if len(resmap) == 0 {
owlhandler.Transmit(NOT_FOUND)
return
}
owlhandler.Transmit(SUCCESS)
w.Header().Set("Content-Type", "application/json; charset=utf-8;")
data, _ := json.Marshal(&resmap)
owlhandler.owlresponse.Data = data
return
}
func (owlhandler *OwlHandler) getWSCData() []OwlResponse {
list := WSClist.GetList()
groupKVlist := group.NewServergroup()
var wg sync.WaitGroup
if len(owlhandler.owlrequest.Target) > 3 {
var prefix string
if owlconfig.OwlConfigModel.Open_Https == "1" {
prefix = "wss://"
} else {
prefix = "ws://"
}
for _, ws := range list {
if owltools.JoinString(prefix, owlhandler.owlrequest.Target, "/ws") == ws.WebSocket.Url {
wg.Add(1)
wsccontent := NewWSCContent(owlhandler.owlrequest.Key, ws.WebSocket.Url)
go owlhandler.parseWSCContent(ws, wsccontent, groupKVlist, &wg)
wg.Wait()
}
}
} else {
for _, ws := range list {
wg.Add(1)
wsccontent := NewWSCContent(owlhandler.owlrequest.Key, ws.WebSocket.Url)
go owlhandler.parseWSCContent(ws, wsccontent, groupKVlist, &wg)
}
wg.Wait()
}
bubblesortlist := owlhandler.bubbleSortContent(groupKVlist)
return bubblesortlist
}
func (owlhandler *OwlHandler) parseWSCContent(ws *websocketclient.OwlWebSocketClient, wsccontent WSCContent, kvlist *group.Servergroup, wg *sync.WaitGroup) {
defer wg.Done()
sql := owltools.JoinString("get ", wsccontent.Key, " info ", wsccontent.Handshake_string)
err := ws.SendTextMessage(sql)
if err == wsc.CloseErr {
owllog.OwlLogWebsocketClient.Info(owltools.JoinString(ws.WebSocket.Url, " OnTextMessageSent error: ", err.Error()))
return
}
to := timeout.New()
str := owltools.JoinString(wsccontent.Key, "@", wsccontent.Handshake_string)
to.SetTimeout(str, time.Second*5)
var resbody OwlResponse
Loop:
for to.CheckTimeout(str) {
time.Sleep(time.Millisecond * 2)
v, b := WSCGroupCacheBurnAfterReading(str)
if b == true {
resbody = JsonStrToOwlResponse(string(v))
resbody.Key = strings.TrimSpace(strings.Split(resbody.Key, "@")[0])
break Loop
}
}
kvlist.Add(resbody)
return
}