Files
bl/common/rpc/rpc.go
昔念 3e1887c7b8 ```
feat(broadcast): 添加全服广播功能并完善相关逻辑

新增 Broadcast 结构体及 Server 的 Broadcast 方法,用于实现全服广播消息,
并在 RPC 客户端中增加对应接口。同时在 fight 模块中添加聊天信息结构体和处理逻辑。

refactor(pet_skill): 优化宠物技能设置逻辑

修复宠物技能替换判断条件错误的问题,并调整相关逻辑顺序以提高代码可读性与健壮性。

feat(chat): 实现战斗内聊天功能

新增战斗中的聊天指令结构体 ChatInfo 和对应的控制器方法 FightChat,
支持玩家在战斗中发送聊天消息。

refactor(item_buy): 调整金币购买道具的扣费方式

将原直接比较金币数量改为调用
2025-11-25 16:36:55 +08:00

152 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package rpc
import (
"blazing/common/data/share"
"blazing/cool"
"sync"
"blazing/modules/base/service"
"context"
"fmt"
"log"
"net/http"
blservice "blazing/modules/blazing/service"
"github.com/filecoin-project/go-jsonrpc"
"github.com/gogf/gf/v2/util/gconv"
)
var rpcport = gconv.String(cool.Config.RPC)
// 定义改为sync.Map
var Clientmap sync.Map
// 存值示例
func addClient(id uint16, client *ClientHandler) {
// 普通mapClientmap[id] = client
Clientmap.Store(id, client) // sync.Map存值
}
// 取值示例
func getClient(id uint16) (*ClientHandler, bool) {
// 普通mapclient, ok := Clientmap[id]
val, ok := Clientmap.Load(id) // sync.Map取值
if !ok {
return nil, false
}
// 类型断言确保value是*ClientHandler
client, ok := val.(*ClientHandler)
return client, ok
}
type ClientHandler struct {
KickPerson func(uint32) error //踢人,这里是返回具体的logic
QuitSelf func(int) error //关闭服务器进程
Broadcast func(string) int //全服广播,返回的是在线人数
}
// Define the server handler
type ServerHandler struct{}
// 实现踢人
func (h *ServerHandler) Kick(ctx context.Context, userid uint32) error {
cool.Loger.Info(context.TODO(), "服务器收到踢人")
useid1, err := share.ShareManager.GetUserOnline(userid)
if err != nil {
return fmt.Errorf("user not found", err)
}
cl, ok := getClient(useid1)
if ok {
err := cl.KickPerson(userid) //实现指定服务器踢人
if err != nil {
return fmt.Errorf("踢人失败", err)
}
}
return nil
}
// 注册logic服务器
func (h *ServerHandler) RegisterLogic(ctx context.Context, id, port uint16) error {
cool.Loger.Debug(context.Background(), "注册logic服务器", id, port)
//TODO 待修复滚动更新可能导致的玩家可以同时在旧服务器和新服务器同时在线的bug
revClient, ok := jsonrpc.ExtractReverseClient[ClientHandler](ctx)
if !ok {
return fmt.Errorf("no reverse client")
}
t, _ := blservice.NewLoginServiceService().GetServerID(id)
aa, ok := getClient(t)
if ok && aa != nil { //如果已经存在且这个端口已经被存过
aa.QuitSelf(0)
}
addClient(port, &revClient)
//Refurh()
return nil
}
func StartServer() {
// create a new server instance
rpcServer := jsonrpc.NewServer(jsonrpc.WithReverseClient[ClientHandler](""))
rpcServer.Register("", &ServerHandler{})
cool.Loger.Debug(context.Background(), "jsonrpc server start", rpcport)
// go time.AfterFunc(3000, func() {
// testjsonrpc()
// })
err := http.ListenAndServe("0.0.0.0:"+rpcport, rpcServer)
cool.Loger.Debug(context.Background(), "jsonrpc server fail", err)
}
var closer jsonrpc.ClientCloser
func StartClient(id, port uint16, callback any) *struct {
Kick func(uint32) error
RegisterLogic func(uint16, uint16) error
} {
var rpcaddr, _ = service.NewBaseSysParamService().DataByKey(context.Background(), "server_ip")
//rpcaddr = "127.0.0.1"
closer1, err := jsonrpc.NewMergeClient(context.Background(),
"ws://"+rpcaddr+":"+rpcport, "", []interface{}{
&RPCClient,
}, nil, jsonrpc.WithClientHandler("", callback),
jsonrpc.WithReconnFun(func() { RPCClient.RegisterLogic(id, port) }),
)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
//if port != 0 { //注册logic
RPCClient.RegisterLogic(id, port)
//}
closer = closer1
return &RPCClient
}
// 关闭客户端
func CloseClient() {
if closer != nil {
closer()
}
}
// Setup RPCClient with reverse call handler
var RPCClient struct {
Kick func(uint32) error //踢人
RegisterLogic func(uint16, uint16) error
// UserLogin func(int32, int32) error //用户登录事件
// UserLogout func(int32, int32) error //用户登出事件
}