Skip to content

Commit 4c6ae1b

Browse files
feat: networked message channel (#605)
* Creating NetworkedMessageChannel
1 parent 8ece56e commit 4c6ae1b

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

Assets/BossRoom/Scripts/Shared/Infrastructure/PubSub/MessageChannel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class MessageChannel<T> : IMessageChannel<T>
1616

1717
public bool IsDisposed { get; private set; } = false;
1818

19-
public void Dispose()
19+
public virtual void Dispose()
2020
{
2121
if (!IsDisposed)
2222
{

Assets/BossRoom/Scripts/Shared/Infrastructure/PubSub/MessageChannelDIExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ public static void BindMessageChannelInstance<TMessage>(this DIScope scope)
66
{
77
scope.BindInstanceAsSingle<MessageChannel<TMessage>, IPublisher<TMessage>, ISubscriber<TMessage>, IMessageChannel<TMessage>>(new MessageChannel<TMessage>());
88
}
9+
public static void BindNetworkedMessageChannelInstance<TMessage>(this DIScope scope) where TMessage : unmanaged
10+
{
11+
scope.BindInstanceAsSingle<NetworkedMessageChannel<TMessage>, IPublisher<TMessage>, ISubscriber<TMessage>, IMessageChannel<TMessage>>(new NetworkedMessageChannel<TMessage>());
12+
}
913

1014
public static void BindBufferedMessageChannelInstance<TMessage>(this DIScope scope)
1115
{
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using Unity.Collections;
3+
using Unity.Netcode;
4+
using UnityEngine;
5+
6+
namespace Unity.Multiplayer.Samples.BossRoom.Shared.Infrastructure
7+
{
8+
/// <summary>
9+
/// This type of message channel allows the server to publish a message that will be sent to clients as well as
10+
/// being published locally. Clients and the server both can subscribe to it. However, that subscription needs to be
11+
/// done after the NetworkManager has initialized. On objects whose lifetime is bigger than a networked session,
12+
/// subscribing will be required each time a new session starts.
13+
/// </summary>
14+
/// <typeparam name="T"></typeparam>
15+
public class NetworkedMessageChannel<T> : MessageChannel<T> where T : unmanaged
16+
{
17+
string m_Name;
18+
19+
bool m_HasRegisteredHandler;
20+
21+
public NetworkedMessageChannel()
22+
{
23+
m_Name = $"{typeof(T).FullName}NetworkMessageChannel";
24+
}
25+
26+
public override void Dispose()
27+
{
28+
if (!IsDisposed)
29+
{
30+
if (NetworkManager.Singleton != null && NetworkManager.Singleton.CustomMessagingManager != null && m_HasRegisteredHandler)
31+
{
32+
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(m_Name);
33+
}
34+
35+
m_HasRegisteredHandler = false;
36+
}
37+
base.Dispose();
38+
}
39+
40+
public override IDisposable Subscribe(Action<T> handler)
41+
{
42+
if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsListening)
43+
{
44+
// Only register message handler on clients
45+
if (!m_HasRegisteredHandler && !NetworkManager.Singleton.IsServer)
46+
{
47+
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(m_Name, ReceiveMessageThroughNetwork);
48+
m_HasRegisteredHandler = true;
49+
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnect;
50+
}
51+
52+
return base.Subscribe(handler);
53+
}
54+
55+
Debug.LogError("Cannot subscribe to NetworkedMessageChannel. NetworkManager is not initialized.");
56+
return null;
57+
}
58+
59+
void OnClientDisconnect(ulong clientId)
60+
{
61+
m_HasRegisteredHandler = false;
62+
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientDisconnect;
63+
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(m_Name);
64+
}
65+
66+
public override void Publish(T message)
67+
{
68+
if (NetworkManager.Singleton.IsServer)
69+
{
70+
// send message to clients, then publish locally
71+
SendMessageThroughNetwork(message);
72+
base.Publish(message);
73+
}
74+
else
75+
{
76+
Debug.LogError("Only a server can publish in a NetworkedMessageChannel");
77+
}
78+
}
79+
80+
void SendMessageThroughNetwork(T message)
81+
{
82+
var writer = new FastBufferWriter(FastBufferWriter.GetWriteSize<T>(), Allocator.Temp);
83+
writer.WriteValueSafe(message);
84+
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(m_Name, writer);
85+
}
86+
87+
void ReceiveMessageThroughNetwork(ulong clientID, FastBufferReader reader)
88+
{
89+
reader.ReadValueSafe(out T message);
90+
base.Publish(message);
91+
}
92+
}
93+
}

Assets/BossRoom/Scripts/Shared/Infrastructure/PubSub/NetworkedMessageChannel.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)