platform: Fix log server

This commit is contained in:
世界 2023-10-02 22:27:48 +08:00
parent 5f2f7fc8b9
commit 45c679648e
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 44 additions and 6 deletions

View file

@ -25,6 +25,7 @@ type CommandClientOptions struct {
type CommandClientHandler interface { type CommandClientHandler interface {
Connected() Connected()
Disconnected(message string) Disconnected(message string)
ClearLog()
WriteLog(message string) WriteLog(message string)
WriteStatus(message *StatusMessage) WriteStatus(message *StatusMessage)
WriteGroups(message OutboundGroupIterator) WriteGroups(message OutboundGroupIterator)

View file

@ -23,6 +23,9 @@ func readLog(reader io.Reader) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if messageLength == 0 {
return nil, nil
}
data := make([]byte, messageLength) data := make([]byte, messageLength)
_, err = io.ReadFull(reader, data) _, err = io.ReadFull(reader, data)
if err != nil { if err != nil {
@ -32,14 +35,24 @@ func readLog(reader io.Reader) ([]byte, error) {
} }
func writeLog(writer io.Writer, message []byte) error { func writeLog(writer io.Writer, message []byte) error {
err := binary.Write(writer, binary.BigEndian, uint16(len(message))) err := binary.Write(writer, binary.BigEndian, uint8(0))
if err != nil { if err != nil {
return err return err
} }
_, err = writer.Write(message) err = binary.Write(writer, binary.BigEndian, uint16(len(message)))
if err != nil {
return err
}
if len(message) > 0 {
_, err = writer.Write(message)
}
return err return err
} }
func writeClearLog(writer io.Writer) error {
return binary.Write(writer, binary.BigEndian, uint8(1))
}
func (s *CommandServer) handleLogConn(conn net.Conn) error { func (s *CommandServer) handleLogConn(conn net.Conn) error {
var savedLines []string var savedLines []string
s.access.Lock() s.access.Lock()
@ -69,6 +82,11 @@ func (s *CommandServer) handleLogConn(conn net.Conn) error {
if err != nil { if err != nil {
return err return err
} }
case <-s.logReset:
err = writeClearLog(conn)
if err != nil {
return err
}
case <-done: case <-done:
return nil return nil
} }
@ -77,12 +95,24 @@ func (s *CommandServer) handleLogConn(conn net.Conn) error {
func (c *CommandClient) handleLogConn(conn net.Conn) { func (c *CommandClient) handleLogConn(conn net.Conn) {
for { for {
message, err := readLog(conn) var messageType uint8
err := binary.Read(conn, binary.BigEndian, &messageType)
if err != nil { if err != nil {
c.handler.Disconnected(err.Error()) c.handler.Disconnected(err.Error())
return return
} }
c.handler.WriteLog(string(message)) var message []byte
switch messageType {
case 0:
message, err = readLog(conn)
if err != nil {
c.handler.Disconnected(err.Error())
return
}
c.handler.WriteLog(string(message))
case 1:
c.handler.ClearLog()
}
} }
} }

View file

@ -23,14 +23,16 @@ type CommandServer struct {
handler CommandServerHandler handler CommandServerHandler
access sync.Mutex access sync.Mutex
savedLines *list.List[string] savedLines list.List[string]
maxLines int maxLines int
subscriber *observable.Subscriber[string] subscriber *observable.Subscriber[string]
observer *observable.Observer[string] observer *observable.Observer[string]
service *BoxService service *BoxService
// These channels only work with a single client. if multi-client support is needed, replace with Subscriber/Observer
urlTestUpdate chan struct{} urlTestUpdate chan struct{}
modeUpdate chan struct{} modeUpdate chan struct{}
logReset chan struct{}
} }
type CommandServerHandler interface { type CommandServerHandler interface {
@ -42,11 +44,11 @@ type CommandServerHandler interface {
func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer { func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer {
server := &CommandServer{ server := &CommandServer{
handler: handler, handler: handler,
savedLines: new(list.List[string]),
maxLines: int(maxLines), maxLines: int(maxLines),
subscriber: observable.NewSubscriber[string](128), subscriber: observable.NewSubscriber[string](128),
urlTestUpdate: make(chan struct{}, 1), urlTestUpdate: make(chan struct{}, 1),
modeUpdate: make(chan struct{}, 1), modeUpdate: make(chan struct{}, 1),
logReset: make(chan struct{}, 1),
} }
server.observer = observable.NewObserver[string](server.subscriber, 64) server.observer = observable.NewObserver[string](server.subscriber, 64)
return server return server
@ -56,6 +58,11 @@ func (s *CommandServer) SetService(newService *BoxService) {
if newService != nil { if newService != nil {
service.PtrFromContext[urltest.HistoryStorage](newService.ctx).SetHook(s.urlTestUpdate) service.PtrFromContext[urltest.HistoryStorage](newService.ctx).SetHook(s.urlTestUpdate)
newService.instance.Router().ClashServer().(*clashapi.Server).SetModeUpdateHook(s.modeUpdate) newService.instance.Router().ClashServer().(*clashapi.Server).SetModeUpdateHook(s.modeUpdate)
s.savedLines.Init()
select {
case s.logReset <- struct{}{}:
default:
}
} }
s.service = newService s.service = newService
s.notifyURLTestUpdate() s.notifyURLTestUpdate()