feat: 实现登录、会话令牌、握手与顶号
EOF
This commit is contained in:
+117
-13
@@ -9,6 +9,7 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.asio.asia/nixevol/NixMsg/internal/app/port"
|
||||
mqtt "github.com/mochi-mqtt/server/v2"
|
||||
@@ -85,18 +86,22 @@ type Broker struct {
|
||||
}
|
||||
|
||||
type connState struct {
|
||||
connID port.ConnID
|
||||
endpointID string
|
||||
transport port.Transport
|
||||
remoteIP string
|
||||
client *mqtt.Client
|
||||
maxPacketSize uint32
|
||||
maxRecvBytes int
|
||||
authOK bool
|
||||
authErr error
|
||||
sessionToken string
|
||||
largeHeld int
|
||||
mu sync.Mutex
|
||||
connID port.ConnID
|
||||
endpointID string
|
||||
transport port.Transport
|
||||
remoteIP string
|
||||
client *mqtt.Client
|
||||
maxPacketSize uint32
|
||||
maxRecvBytes int
|
||||
authOK bool
|
||||
authErr error
|
||||
sessionToken string
|
||||
handshook bool
|
||||
subscribedDown bool
|
||||
largeHeld int
|
||||
mu sync.Mutex
|
||||
|
||||
handshakeTimer *time.Timer
|
||||
}
|
||||
|
||||
// New 创建并 Serve mochi(无监听器)。
|
||||
@@ -265,7 +270,12 @@ func (b *Broker) Disconnect(_ context.Context, endpointID string, connID port.Co
|
||||
case port.DisconnectKicked, port.DisconnectFatal:
|
||||
code = packets.ErrAdministrativeAction
|
||||
}
|
||||
return b.server.DisconnectClient(st.client, code)
|
||||
err := b.server.DisconnectClient(st.client, code)
|
||||
// mochi 对错误类原因码会把 Code 当作 error 返回,表示已按该原因断开,不算失败。
|
||||
if _, ok := err.(packets.Code); ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *Broker) lookupConn(endpointID string, connID port.ConnID) *connState {
|
||||
@@ -362,6 +372,100 @@ func (b *Broker) ConnInfoOf(endpointID string) (port.ConnInfo, bool) {
|
||||
}, true
|
||||
}
|
||||
|
||||
// IsHandshook 当前连接是否已完成握手。
|
||||
func (b *Broker) IsHandshook(endpointID string) bool {
|
||||
b.connsMu.RLock()
|
||||
st := b.current[endpointID]
|
||||
b.connsMu.RUnlock()
|
||||
if st == nil {
|
||||
return false
|
||||
}
|
||||
st.mu.Lock()
|
||||
defer st.mu.Unlock()
|
||||
return st.handshook
|
||||
}
|
||||
|
||||
// CurrentConnID 返回端的当前连接代号。
|
||||
func (b *Broker) CurrentConnID(endpointID string) (port.ConnID, bool) {
|
||||
b.connsMu.RLock()
|
||||
st := b.current[endpointID]
|
||||
b.connsMu.RUnlock()
|
||||
if st == nil {
|
||||
return "", false
|
||||
}
|
||||
return st.connID, true
|
||||
}
|
||||
|
||||
func (b *Broker) connStateOf(endpointID string, connID port.ConnID) *connState {
|
||||
b.connsMu.RLock()
|
||||
defer b.connsMu.RUnlock()
|
||||
for _, st := range b.byClient {
|
||||
if st.endpointID == endpointID && st.connID == connID {
|
||||
return st
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Broker) hasDownSub(st *connState) bool {
|
||||
if st == nil {
|
||||
return false
|
||||
}
|
||||
st.mu.Lock()
|
||||
defer st.mu.Unlock()
|
||||
if st.subscribedDown {
|
||||
return true
|
||||
}
|
||||
// 回退:直接看 mochi 订阅表
|
||||
if st.client != nil && st.client.State.Subscriptions != nil {
|
||||
_, ok := st.client.State.Subscriptions.Get(downTopic(st.endpointID))
|
||||
return ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Broker) startHandshakeDeadline(endpointID string, connID port.ConnID, d time.Duration) {
|
||||
st := b.connStateOf(endpointID, connID)
|
||||
if st == nil {
|
||||
return
|
||||
}
|
||||
st.mu.Lock()
|
||||
if st.handshook {
|
||||
st.mu.Unlock()
|
||||
return
|
||||
}
|
||||
if st.handshakeTimer != nil {
|
||||
st.handshakeTimer.Stop()
|
||||
}
|
||||
st.handshakeTimer = time.AfterFunc(d, func() {
|
||||
cur := b.connStateOf(endpointID, connID)
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
cur.mu.Lock()
|
||||
done := cur.handshook
|
||||
cur.mu.Unlock()
|
||||
if done {
|
||||
return
|
||||
}
|
||||
_ = b.Disconnect(context.Background(), endpointID, connID, port.DisconnectIdle)
|
||||
})
|
||||
st.mu.Unlock()
|
||||
}
|
||||
|
||||
func (b *Broker) cancelHandshakeDeadline(endpointID string, connID port.ConnID) {
|
||||
st := b.connStateOf(endpointID, connID)
|
||||
if st == nil {
|
||||
return
|
||||
}
|
||||
st.mu.Lock()
|
||||
if st.handshakeTimer != nil {
|
||||
st.handshakeTimer.Stop()
|
||||
st.handshakeTimer = nil
|
||||
}
|
||||
st.mu.Unlock()
|
||||
}
|
||||
|
||||
func (b *Broker) enqueueUplink(endpointID string, conn port.ConnInfo, payload []byte) {
|
||||
b.queuesMu.Lock()
|
||||
q, ok := b.queues[endpointID]
|
||||
|
||||
Reference in New Issue
Block a user