Can not receive command, but can receive event
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.
Could you post your sample code please?
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
}
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}");
}
}
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; }
}
Eventhandler works well,so I just post the command code here.
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.
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?
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.
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.
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.
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.
Got it!