115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package battle
|
|
|
|
import (
|
|
"context"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"sync"
|
|
|
|
"go_dreamfactory/lego/core"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
)
|
|
|
|
/*
|
|
战斗服务客户端组件
|
|
*/
|
|
type clientComp struct {
|
|
modules.MCompGate
|
|
options *Options
|
|
service core.IService
|
|
module *Battle
|
|
conn *websocket.Conn
|
|
seq uint64
|
|
pendingmutex sync.Mutex
|
|
pending map[uint64]*MessageCall //高并发回调
|
|
}
|
|
|
|
//组件初始化接口
|
|
func (this *clientComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
|
this.MCompGate.Init(service, module, comp, options)
|
|
this.options = options.(*Options)
|
|
this.module = module.(*Battle)
|
|
this.pending = make(map[uint64]*MessageCall)
|
|
return
|
|
}
|
|
|
|
func (this *clientComp) Start() (err error) {
|
|
err = this.MCompGate.Start()
|
|
dialer := websocket.Dialer{}
|
|
this.conn, _, err = dialer.Dial(this.options.BattleServerAddr, nil)
|
|
return
|
|
}
|
|
|
|
//校验战斗过程
|
|
func (this *clientComp) callBattle(ctx context.Context, method string, req proto.Message, reply proto.Message) (err error) {
|
|
call := new(MessageCall)
|
|
call.Done = make(chan *MessageCall, 10)
|
|
call.Args = req
|
|
call.Reply = reply
|
|
this.pendingmutex.Lock()
|
|
seq := this.seq
|
|
this.seq++
|
|
this.pending[seq] = call
|
|
this.pendingmutex.Unlock()
|
|
msg := &pb.BattleRpcMessage{
|
|
Rid: seq,
|
|
Method: method,
|
|
}
|
|
msg.Data, _ = anypb.New(req)
|
|
data, _ := proto.Marshal(msg)
|
|
if err = this.conn.WriteMessage(websocket.BinaryMessage, data); err != nil {
|
|
this.pendingmutex.Lock()
|
|
delete(this.pending, seq)
|
|
this.pendingmutex.Unlock()
|
|
return
|
|
}
|
|
select {
|
|
case <-ctx.Done(): // cancel by context
|
|
this.pendingmutex.Lock()
|
|
call := this.pending[seq]
|
|
delete(this.pending, seq)
|
|
this.pendingmutex.Unlock()
|
|
if call != nil {
|
|
call.Error = ctx.Err()
|
|
call.done(this.options.Log)
|
|
}
|
|
return ctx.Err()
|
|
case call := <-call.Done:
|
|
err = call.Error
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *clientComp) run() {
|
|
var (
|
|
data []byte
|
|
msg *pb.BattleRpcMessage = &pb.BattleRpcMessage{}
|
|
err error
|
|
)
|
|
locp:
|
|
for {
|
|
if _, data, err = this.conn.ReadMessage(); err != nil {
|
|
this.module.Errorf("client err:%v", err)
|
|
break locp
|
|
}
|
|
if err = proto.Unmarshal(data, msg); err != nil {
|
|
this.module.Errorf("client Unmarshal err:%v", err)
|
|
break locp
|
|
}
|
|
go this.handleresponse(msg)
|
|
}
|
|
}
|
|
|
|
func (this *clientComp) handleresponse(resp *pb.BattleRpcMessage) {
|
|
var call *MessageCall
|
|
this.pendingmutex.Lock()
|
|
call = this.pending[resp.Rid]
|
|
delete(this.pending, resp.Rid)
|
|
this.pendingmutex.Unlock()
|
|
call.Error = resp.Data.UnmarshalTo(call.Reply)
|
|
call.done(this.options.Log)
|
|
}
|