topfreegames / pitaya

Scalable game server framework with clustering support and client libraries for iOS, Android, Unity and others through the C SDK.
MIT License
2.38k stars 480 forks source link

Unable to receive Push messages when using Unity SDK #410

Open LacusCon opened 4 months ago

LacusCon commented 4 months ago

When I use Unity SDK, I can use request and response messages, but I can't receive messages from the server through Session Push. I have already registered through OnRoute

felipejfc commented 4 months ago

can you share a reproduction repo / zip

LacusCon commented 4 months ago

Without using builder.Serializer = protobuf.NewSerializer(), push string is successful. When protobuf is enabled, push string or proto will fail. [fail code1] func (s PushAbout) PushTest(ctx context.Context) (proto.CommonResp, error) { resp := &proto.CommonResp{Err: proto.ErrCodeOK} session := s.app.GetSessionFromCtx(ctx) = session.Push("push.lobby.game_state", resp) return resp, nil } [log1] level=debug msg="Type=Push, ID=1, UID=, Route=push.lobby.game_state, Data=" source=pitaya [client not receive]

[fail code2] func (s PushAbout) PushTest(ctx context.Context) (proto.CommonResp, error) { resp := &proto.CommonResp{Err: proto.ErrCodeOK} session := s.app.GetSessionFromCtx(ctx) = session.Push("push.lobby.game_state", *resp) return resp, nil } [log2] level=debug msg="Type=Push, ID=1, UID=, Route=push.lobby.game_state, Data={state:{NoUnkeyedLiterals:{} DoNotCompare:[] DoNotCopy:[] atomicMessageInfo:} sizeCache:0 unknownFields:[] Err:OK}" source=pitaya [client log] PIT-000 %protobuf: convert on wrong type value

LacusCon commented 4 months ago

I found the cause of this problem. It was caused by Marshal(m Message) ([]byte, error). If the proto message uses the default value, there will be a problem. enum ErrCode { OK = 0; ERR = 1; } message CommonResp { ErrCode err = 1; } [code]: resp1 := &proto.CommonResp{Err: proto.ErrCode_OK} session.Push("test.x.y", resp1) [failed]: image

[code]: resp2 := &proto.CommonResp{Err: proto.ErrCode_ERR} session.Push("test.x.y", resp2) [success]: image

filipemeneses commented 3 months ago

I had a similar issue with SendPushToUsers, an empty proto message doesn't throw any exceptions nor calls the client listener, to fix this, I added an arbitrary attribute called status to the proto and worked

// base.proto

syntax = "proto3";

package protos;

message MyResponse {
+  bool status = 1;
}
// usage.go
pushResponse := &protos.MyResponse{
+  Status: true,
}

pitayaInstance.SendPushToUsers("myRoute", pushResponse, myUsers, "myType")
renatoaf commented 3 months ago

We went through this recently in one of our projects. The problem is in the libpitaya c code: https://github.com/topfreegames/libpitaya/blob/master/src/pc_trans.c#L244

Zero-length messages are ignored on pushes, so it never reaches the C# code where messages would be unmarshalled / callbacks invoked.