parent
52eea69cd0
commit
87b0ae6cec
@ -0,0 +1,65 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/core"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/entity"
|
||||||
|
"git.noahlan.cn/noahlan/ntools-go/core/nlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OnReadyFunc func()
|
||||||
|
|
||||||
|
func WithNNetClientPipeline(onReady OnReadyFunc) core.RunOption {
|
||||||
|
packer := NewNNetPacker()
|
||||||
|
return func(server *core.NNet) {
|
||||||
|
server.Pipeline().Inbound().PushFront(func(entity entity.NetworkEntity, v interface{}) error {
|
||||||
|
pkg, ok := v.(*NNetPacket)
|
||||||
|
if !ok {
|
||||||
|
return ErrWrongPacketType
|
||||||
|
}
|
||||||
|
conn, _ := entity.Conn()
|
||||||
|
|
||||||
|
// Server to client
|
||||||
|
switch pkg.PacketType {
|
||||||
|
case Handshake:
|
||||||
|
var handshakeData HandshakeResp
|
||||||
|
err := json.Unmarshal(pkg.Data, &handshakeData)
|
||||||
|
nlog.Must(err)
|
||||||
|
|
||||||
|
hrd, _ := packer.Pack(Header{
|
||||||
|
PacketType: HandshakeAck,
|
||||||
|
MessageHeader: MessageHeader{},
|
||||||
|
}, nil)
|
||||||
|
if err := entity.SendBytes(hrd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
entity.SetStatus(core.StatusWorking)
|
||||||
|
// onReady
|
||||||
|
if onReady != nil {
|
||||||
|
onReady()
|
||||||
|
}
|
||||||
|
nlog.Debugf("connection handshake Id=%d, Remote=%s", entity.Session().ID(), conn.RemoteAddr())
|
||||||
|
case Kick:
|
||||||
|
_ = entity.Close()
|
||||||
|
case Data:
|
||||||
|
status := entity.Status()
|
||||||
|
if status != core.StatusWorking {
|
||||||
|
return errors.New(fmt.Sprintf("receive data on socket which not yet ACK, session will be closed immediately, remote=%s",
|
||||||
|
conn.RemoteAddr()))
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastMid uint64
|
||||||
|
switch pkg.MsgType {
|
||||||
|
case Response:
|
||||||
|
lastMid = pkg.ID
|
||||||
|
case Notify:
|
||||||
|
lastMid = 0
|
||||||
|
}
|
||||||
|
entity.SetLastMID(lastMid)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/config"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/core"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/entity"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/packet"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/protocol"
|
||||||
|
"git.noahlan.cn/noahlan/ntools-go/core/nlog"
|
||||||
|
"git.noahlan.cn/noahlan/ntools-go/core/pool"
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func runServer(addr string) {
|
||||||
|
server := core.NewServer(config.EngineConf{
|
||||||
|
ServerConf: config.ServerConf{
|
||||||
|
Protocol: "tcp",
|
||||||
|
Addr: addr,
|
||||||
|
Name: "testServer",
|
||||||
|
Mode: "dev",
|
||||||
|
},
|
||||||
|
Pool: pool.Config{
|
||||||
|
PoolSize: math.MaxInt32,
|
||||||
|
ExpiryDuration: time.Second,
|
||||||
|
PreAlloc: false,
|
||||||
|
MaxBlockingTasks: 0,
|
||||||
|
Nonblocking: false,
|
||||||
|
DisablePurge: false,
|
||||||
|
},
|
||||||
|
}, protocol.WithNNetProtocol(protocol.NNetConfig{
|
||||||
|
HeartbeatInterval: 0,
|
||||||
|
HandshakeValidator: nil,
|
||||||
|
})...)
|
||||||
|
|
||||||
|
server.AddRoutes([]core.Route{
|
||||||
|
{
|
||||||
|
Matches: protocol.Match{
|
||||||
|
Route: "ping",
|
||||||
|
Code: 1,
|
||||||
|
},
|
||||||
|
Handler: func(et entity.NetworkEntity, pkg packet.IPacket) {
|
||||||
|
nlog.Info("client ping, server pong -> ")
|
||||||
|
err := et.Send(protocol.Header{
|
||||||
|
PacketType: protocol.Data,
|
||||||
|
MessageHeader: protocol.MessageHeader{
|
||||||
|
MsgType: protocol.Request,
|
||||||
|
ID: 1,
|
||||||
|
Route: "pong",
|
||||||
|
},
|
||||||
|
}, []byte("1"))
|
||||||
|
nlog.Must(err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
defer server.Stop()
|
||||||
|
server.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runClient(addr string) (client *core.Client, et entity.NetworkEntity) {
|
||||||
|
chReady := make(chan struct{})
|
||||||
|
client = core.NewClient(config.EngineConf{
|
||||||
|
Pool: pool.Config{
|
||||||
|
PoolSize: math.MaxInt32,
|
||||||
|
ExpiryDuration: time.Second,
|
||||||
|
PreAlloc: false,
|
||||||
|
MaxBlockingTasks: 0,
|
||||||
|
Nonblocking: false,
|
||||||
|
DisablePurge: false,
|
||||||
|
},
|
||||||
|
}, protocol.WithNNetClientProtocol(func() {
|
||||||
|
chReady <- struct{}{}
|
||||||
|
})...)
|
||||||
|
|
||||||
|
client.AddRoutes([]core.Route{
|
||||||
|
{
|
||||||
|
Matches: protocol.Match{
|
||||||
|
Route: "test.client",
|
||||||
|
Code: 1,
|
||||||
|
},
|
||||||
|
Handler: func(et entity.NetworkEntity, pkg packet.IPacket) {
|
||||||
|
nlog.Info("client hahaha")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
et = client.Dial(addr)
|
||||||
|
|
||||||
|
handshake, err := json.Marshal(&protocol.HandshakeReq{
|
||||||
|
Version: "1.0.0",
|
||||||
|
Type: "test",
|
||||||
|
ClientId: "a",
|
||||||
|
ClientSecret: "a",
|
||||||
|
Payload: map[string]string{
|
||||||
|
"pl": "test-data",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
nlog.Must(err)
|
||||||
|
|
||||||
|
packer := protocol.NewNNetPacker()
|
||||||
|
hsd, err := packer.Pack(protocol.Header{
|
||||||
|
PacketType: protocol.Handshake,
|
||||||
|
MessageHeader: protocol.MessageHeader{
|
||||||
|
MsgType: 0,
|
||||||
|
ID: 0,
|
||||||
|
Route: "",
|
||||||
|
},
|
||||||
|
}, handshake)
|
||||||
|
nlog.Must(err)
|
||||||
|
|
||||||
|
err = et.SendBytes(hsd)
|
||||||
|
nlog.Must(err)
|
||||||
|
|
||||||
|
<-chReady
|
||||||
|
return
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.noahlan.cn/noahlan/nnet/core"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/entity"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/packet"
|
||||||
|
"git.noahlan.cn/noahlan/nnet/protocol"
|
||||||
|
"git.noahlan.cn/noahlan/ntools-go/core/nlog"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServer(t *testing.T) {
|
||||||
|
runServer("0.0.0.0:6666")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient(t *testing.T) {
|
||||||
|
client, et := runClient("127.0.0.1:6666")
|
||||||
|
client.AddRoute(core.Route{
|
||||||
|
Matches: protocol.Match{
|
||||||
|
Route: "pong",
|
||||||
|
Code: 2,
|
||||||
|
},
|
||||||
|
Handler: func(et entity.NetworkEntity, pkg packet.IPacket) {
|
||||||
|
nlog.Info("server pong, client ping ->")
|
||||||
|
_ = et.Send(protocol.Header{
|
||||||
|
PacketType: protocol.Data,
|
||||||
|
MessageHeader: protocol.MessageHeader{
|
||||||
|
MsgType: protocol.Request,
|
||||||
|
ID: 1,
|
||||||
|
Route: "ping",
|
||||||
|
},
|
||||||
|
}, []byte("1"))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_ = et.Send(protocol.Header{
|
||||||
|
PacketType: protocol.Data,
|
||||||
|
MessageHeader: protocol.MessageHeader{
|
||||||
|
MsgType: protocol.Request,
|
||||||
|
ID: 1,
|
||||||
|
Route: "ping",
|
||||||
|
},
|
||||||
|
}, []byte("1"))
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
Loading…
Reference in New Issue