新增 event , 优化 websocket
This commit is contained in:
@@ -58,8 +58,8 @@ func FilterInstGoJa(gl core.Params) (core.FilterInstance, error) {
|
||||
stop := make(chan struct{}, 1)
|
||||
shutdown := make(chan struct{}, 1)
|
||||
defer close(shutdown)
|
||||
timeout, cancelFunc := context.WithTimeout(ctx, global.Timeout)
|
||||
defer cancelFunc()
|
||||
timeout, timeoutCancelFunc := context.WithTimeout(ctx, global.Timeout)
|
||||
defer timeoutCancelFunc()
|
||||
count := 0
|
||||
closers := NewClosers()
|
||||
defer closers.Close()
|
||||
@@ -84,9 +84,12 @@ func FilterInstGoJa(gl core.Params) (core.FilterInstance, error) {
|
||||
if err = KVInject(ctx, vm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err = EventInject(ctx, vm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if global.EnableWebsocket {
|
||||
var closer io.Closer
|
||||
closer, err = WebsocketInject(vm, debug, request, cancelFunc)
|
||||
closer, err = WebsocketInject(ctx, vm, debug, request, timeoutCancelFunc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
43
pkg/filters/goja/var_event.go
Normal file
43
pkg/filters/goja/var_event.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package goja
|
||||
|
||||
import (
|
||||
"github.com/dop251/goja"
|
||||
"gopkg.d7z.net/gitea-pages/pkg/core"
|
||||
)
|
||||
|
||||
func EventInject(ctx core.FilterContext, jsCtx *goja.Runtime) error {
|
||||
return jsCtx.GlobalObject().Set("event", map[string]interface{}{
|
||||
"subscribe": func(key string) (map[string]any, error) {
|
||||
subscribe, err := ctx.Event.Subscribe(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]any{
|
||||
"on": func(f func(string)) {
|
||||
go func() {
|
||||
z:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break z
|
||||
case data := <-subscribe:
|
||||
f(data)
|
||||
}
|
||||
}
|
||||
}()
|
||||
},
|
||||
"get": func() (string, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
case data := <-subscribe:
|
||||
return data, nil
|
||||
}
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
"put": func(key, value string) error {
|
||||
return ctx.Event.Publish(ctx, key, value)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -50,6 +50,9 @@ func RequestInject(ctx core.FilterContext, jsCtx *goja.Runtime, req *http.Reques
|
||||
}
|
||||
return nil
|
||||
},
|
||||
"getQuery": func(key string) string {
|
||||
return req.URL.Query().Get(key)
|
||||
},
|
||||
"getHeader": func(name string) string {
|
||||
return req.Header.Get(name)
|
||||
},
|
||||
|
||||
@@ -4,14 +4,16 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.d7z.net/gitea-pages/pkg/core"
|
||||
)
|
||||
|
||||
func WebsocketInject(jsCtx *goja.Runtime, w http.ResponseWriter, request *http.Request, cancelFunc context.CancelFunc) (io.Closer, error) {
|
||||
func WebsocketInject(ctx core.FilterContext, jsCtx *goja.Runtime, w http.ResponseWriter, request *http.Request, cancelFunc context.CancelFunc) (io.Closer, error) {
|
||||
closers := NewClosers()
|
||||
return closers, jsCtx.GlobalObject().Set("websocket", func() (any, error) {
|
||||
upgrader := websocket.Upgrader{}
|
||||
@@ -20,9 +22,44 @@ func WebsocketInject(jsCtx *goja.Runtime, w http.ResponseWriter, request *http.R
|
||||
return nil, err
|
||||
}
|
||||
cancelFunc()
|
||||
go func() {
|
||||
ticker := time.NewTicker(15 * time.Second)
|
||||
defer ticker.Stop()
|
||||
f:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break f
|
||||
case <-ticker.C:
|
||||
}
|
||||
if err := conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(5*time.Second)); err != nil {
|
||||
zap.L().Debug("websocket ping failed", zap.Error(err))
|
||||
ctx.Kill()
|
||||
}
|
||||
}
|
||||
}()
|
||||
zap.L().Debug("websocket upgrader created")
|
||||
closers.AddCloser(conn.Close)
|
||||
return map[string]interface{}{
|
||||
"on": func(f func(mType int, message string)) {
|
||||
go func() {
|
||||
z:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break z
|
||||
default:
|
||||
messageType, p, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
break z
|
||||
}
|
||||
f(messageType, string(p))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}()
|
||||
},
|
||||
"TypeTextMessage": websocket.TextMessage,
|
||||
"TypeBinaryMessage": websocket.BinaryMessage,
|
||||
"readText": func() (string, error) {
|
||||
@@ -60,6 +97,9 @@ func WebsocketInject(jsCtx *goja.Runtime, w http.ResponseWriter, request *http.R
|
||||
}
|
||||
return conn.WriteMessage(mType, dataRaw)
|
||||
},
|
||||
"ping": func() error {
|
||||
return conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(1*time.Second))
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user