Zebus icon indicating copy to clipboard operation
Zebus copied to clipboard

Can not receive command, but can receive event

Open playg8 opened this issue 3 years ago • 11 comments

My code is simple,just receive and send as the sample. But not same. No error, no warning,application A can send and receive but the other one can not receive command.

playg8 avatar Apr 09 '22 11:04 playg8

Could you post your sample code please?

MendelMonteiro avatar Apr 09 '22 12:04 MendelMonteiro

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Abc.Zebus.Core;
using Abc.Zebus;
using System.Threading.Tasks;
using System.Threading;
using StructureMap;

public class NetWork : MonoBehaviour
{
    private BusFactory busFactory;
    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

    public IBus bus;

    public static void Init() {
        Init(true);
    }
    public static void Init(bool keepalive) {
        if (_instance == null) {
            GameObject obj = new GameObject("NetWork");
            _instance = obj.AddComponent<NetWork>();
        } else {
            throw new System.Exception("Instance object can not init twice");
        }

        if (true == keepalive) {
            DontDestroyOnLoad(_instance.gameObject);
            DontDestroyOnLoad(_instance);
        }
    }

    // Start is called before the first frame update
    void Start() {
        UnityEngine.Debug.Log($"Creating bus factory");
        busFactory = new BusFactory().WithScan()
                         .WithConfiguration("tcp://localhost:1999", "Demo")
                         //.WithConfiguration("tcp://localhost:129", "Demo")
                         .WithPeerId("BusMg.*");
        UnityEngine.Debug.Log($"Creating bus");
        bus = busFactory.CreateBus();
        UnityEngine.Debug.Log($"Starting bus");
        bus.Started += Bus_Started;
        bus.Stopping += Bus_Stopping;
        bus.Stopped += Bus_Stopped;
        bus.Start();
    }

    private void Bus_Stopped() {
        UnityEngine.Debug.Log($"Bus stopped");
    }

    private void Bus_Stopping() {
        UnityEngine.Debug.Log($"Bus stopping"); 
    }

    private void Bus_Started() {
        UnityEngine.Debug.Log($"Bus started");
    }

    public void SendCmd(ICommand cmd) {
        UnityEngine.Debug.Log($"Sending cmd {cmd.ToString()}");

        bus.Send(cmd);
    }
    public void SendCmdAsync(ICommand cmd) {
        UnityEngine.Debug.Log($"Sending cmd {cmd.ToString()}");
        Task.Run(() => {
            bus.Send(cmd).Wait(cancellationTokenSource.Token);
        });
    }
    public void PublishEvent(IEvent evt) {
        bus.Publish(evt);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S)) {
            SendCmd(new MakeTeaCommand() { OrderNum = UnityEngine.Random.Range(0, 1000) });
        }
        if (Input.GetKeyDown(KeyCode.E)) {
            PublishEvent(new TalkEvent() { Content = "Test" });
        }
    }

    private void OnDestroy() {
        bus.Dispose();
        cancellationTokenSource.Cancel();
        busFactory = null;

        _instance = null;
    }

    #region 属性
    private static NetWork _instance;
    public static NetWork Instance {
        get {
            return _instance;
        }
    }
    #endregion
}

playg8 avatar Apr 09 '22 12:04 playg8

using Abc.Zebus;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;

public class MakeTeaCommandHandler : ICommandHandler<MakeTeaCommand> {
    public void Handle(MakeTeaCommand message) {
        UnityEngine.Debug.Log($"Got command MakeTeaCommand orderNum:{message.OrderNum}");
    }
}

playg8 avatar Apr 09 '22 12:04 playg8

using Abc.Zebus;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ProtoBuf;

[ProtoContract]
public class MakeTeaCommand : ICommand
{
    [ProtoMember(1, IsRequired = true)]
    public int OrderNum { get; set; }
}

playg8 avatar Apr 09 '22 12:04 playg8

Eventhandler works well,so I just post the command code here.

playg8 avatar Apr 09 '22 12:04 playg8

I can see you're using a transient peer (the * in .WithPeerId("BusMg.*")). Commands are designed to be handled by persistent services, not by transient peers like the one you have here.

By design, commands are expected to be handled by a single peer, otherwise sending the command will fail (you can also send a command to a specific peer by using the Send(ICommand message, Peer peer) overload, but it needs to be a single peer either way).

I suppose you have several peers in the directory, especially since you're not stopping the bus (they need to timeout before being decommissioned).

To be honest, Zebus was designed to support a SOA infrastructure, it wasn't really designed for games, so you may encounter other rough edges like that.

ltrzesniewski avatar Apr 09 '22 12:04 ltrzesniewski

Got it.I want use this on a chess game.So this framework is good enough for me.Another question,how can I get other peers that online?

playg8 avatar Apr 09 '22 13:04 playg8

Another question,how can I get other peers that online?

This info is provided by the peer directory, which you can get with busFactory.Container.GetInstance<IPeerDirectory>(). Use the GetPeerDescriptors() method.

ltrzesniewski avatar Apr 09 '22 14:04 ltrzesniewski

Then can I group peers online?I want make some peers in one group like a room in game.Do the frame support do this or I can do this by other ways?Because I want the peers in one room communicate with each other ,others outside do not need listen to the events or command of the room.

playg8 avatar Apr 10 '22 02:04 playg8

I tested this on Android.When it creating a bus, an error of directory throw out, may be directory path is different from windows.May be more error on ios or mac.

playg8 avatar Apr 10 '22 07:04 playg8

Then can I group peers online?I want make some peers in one group like a room in game.Do the frame support do this or I can do this by other ways?Because I want the peers in one room communicate with each other ,others outside do not need listen to the events or command of the room.

You could use the routing feature.

I tested this on Android.When it creating a bus, an error of directory throw out, may be directory path is different from windows.May be more error on ios or mac.

Zebus won't work on Android, as you're probably using an ARM CPU. It has a dependency on the native ZMQ library, which we ship for Windows x86/x64 and Linux x64.

ltrzesniewski avatar Apr 10 '22 10:04 ltrzesniewski

Got it!

playg8 avatar Apr 17 '23 02:04 playg8