diff --git a/lib/realtime_web/channels/realtime_channel/broadcast_handler.ex b/lib/realtime_web/channels/realtime_channel/broadcast_handler.ex index 4251f5787..a89355316 100644 --- a/lib/realtime_web/channels/realtime_channel/broadcast_handler.ex +++ b/lib/realtime_web/channels/realtime_channel/broadcast_handler.ex @@ -129,7 +129,8 @@ defmodule RealtimeWeb.RealtimeChannel.BroadcastHandler do @dialyzer {:nowarn_function, build_broadcast: 2} # Message payload was built by V2 Serializer which was originally UserBroadcastPush - defp build_broadcast(topic, {user_event, user_payload_encoding, user_payload}) do + # We are not using the metadata for anything just yet. + defp build_broadcast(topic, {user_event, user_payload_encoding, user_payload, _metadata}) do %RealtimeWeb.Socket.UserBroadcast{ topic: topic, user_event: user_event, diff --git a/lib/realtime_web/socket/v2_serializer.ex b/lib/realtime_web/socket/v2_serializer.ex index 5fc02aa5b..ff50dab5d 100644 --- a/lib/realtime_web/socket/v2_serializer.ex +++ b/lib/realtime_web/socket/v2_serializer.ex @@ -183,21 +183,30 @@ defmodule RealtimeWeb.Socket.V2Serializer do ref_size::size(8), topic_size::size(8), user_event_size::size(8), + metadata_size::size(8), user_payload_encoding::size(8), join_ref::binary-size(join_ref_size), ref::binary-size(ref_size), topic::binary-size(topic_size), user_event::binary-size(user_event_size), + metadata::binary-size(metadata_size), user_payload::binary >>) do user_payload_encoding = if user_payload_encoding == 0, do: :binary, else: :json + metadata = + if metadata_size > 0 do + Phoenix.json_library().decode!(metadata) + else + %{} + end + # Encoding as Message because that's how Phoenix Socket and Channel.Server expects things to show up - # Here we abuse the payload field to carry a tuple of (user_event, user payload encoding, user payload) + # Here we abuse the payload field to carry a tuple of (user_event, user payload encoding, user payload, metadata) %Message{ topic: topic, event: "broadcast", - payload: {user_event, user_payload_encoding, user_payload}, + payload: {user_event, user_payload_encoding, user_payload, metadata}, ref: ref, join_ref: join_ref } diff --git a/mix.exs b/mix.exs index 3c3287eab..6e4dc445a 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Realtime.MixProject do def project do [ app: :realtime, - version: "2.65.3", + version: "2.66.0", elixir: "~> 1.18", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, diff --git a/test/realtime_web/channels/realtime_channel/broadcast_handler_test.exs b/test/realtime_web/channels/realtime_channel/broadcast_handler_test.exs index 61e680ee4..d15d8c753 100644 --- a/test/realtime_web/channels/realtime_channel/broadcast_handler_test.exs +++ b/test/realtime_web/channels/realtime_channel/broadcast_handler_test.exs @@ -286,7 +286,7 @@ defmodule RealtimeWeb.RealtimeChannel.BroadcastHandlerTest do json_encoded_user_broadcast_payload = Jason.encode!(user_broadcast_payload) {:reply, :ok, _socket} = - BroadcastHandler.handle({"event123", :json, json_encoded_user_broadcast_payload}, db_conn, socket) + BroadcastHandler.handle({"event123", :json, json_encoded_user_broadcast_payload, %{}}, db_conn, socket) topic = "realtime:#{topic}" assert_receive {:socket_push, code, data} @@ -327,7 +327,7 @@ defmodule RealtimeWeb.RealtimeChannel.BroadcastHandlerTest do user_broadcast_payload = <<123, 456, 789>> {:reply, :ok, _socket} = - BroadcastHandler.handle({"event123", :binary, user_broadcast_payload}, db_conn, socket) + BroadcastHandler.handle({"event123", :binary, user_broadcast_payload, %{}}, db_conn, socket) topic = "realtime:#{topic}" diff --git a/test/realtime_web/socket/v2_serializer_test.exs b/test/realtime_web/socket/v2_serializer_test.exs index 3bebb337d..2d83e1ea1 100644 --- a/test/realtime_web/socket/v2_serializer_test.exs +++ b/test/realtime_web/socket/v2_serializer_test.exs @@ -40,6 +40,8 @@ defmodule RealtimeWeb.Socket.V2SerializerTest do 5, # user_event_size 10, + # metadata_size + 0, # binary encoding 0::size(8), "12", @@ -62,6 +64,8 @@ defmodule RealtimeWeb.Socket.V2SerializerTest do 5, # user_event_size 10, + # metadata_size + 0, # json encoding 1::size(8), "12", @@ -79,6 +83,31 @@ defmodule RealtimeWeb.Socket.V2SerializerTest do 125 >> + @client_binary_user_broadcast_push_with_metadata << + # user broadcast push + 3::size(8), + # join_ref_size + 2, + # ref_size + 3, + # topic_size + 5, + # user_event_size + 10, + # metadata_size + 14, + # binary encoding + 0::size(8), + "12", + "123", + "topic", + "user_event", + ~s<{"store":true}>, + 101, + 102, + 103 + >> + @reply << # reply 1::size(8), @@ -490,13 +519,24 @@ defmodule RealtimeWeb.Socket.V2SerializerTest do } end + test "binary user pushed message with metadata" do + assert decode!(@serializer, @client_binary_user_broadcast_push_with_metadata, opcode: :binary) == + %Phoenix.Socket.Message{ + join_ref: "12", + ref: "123", + topic: "topic", + event: "broadcast", + payload: {"user_event", :binary, <<101, 102, 103>>, %{"store" => true}} + } + end + test "binary user pushed message" do assert decode!(@serializer, @client_binary_user_broadcast_push, opcode: :binary) == %Phoenix.Socket.Message{ join_ref: "12", ref: "123", topic: "topic", event: "broadcast", - payload: {"user_event", :binary, <<101, 102, 103>>} + payload: {"user_event", :binary, <<101, 102, 103>>, %{}} } end @@ -506,7 +546,7 @@ defmodule RealtimeWeb.Socket.V2SerializerTest do ref: "123", topic: "topic", event: "broadcast", - payload: {"user_event", :json, "{\"a\":\"b\"}"} + payload: {"user_event", :json, "{\"a\":\"b\"}", %{}} } end end