Open dlobo opened 3 years ago
Isn't this "on you" ? I.e you have to "scope" the join w/ a session ID you create; that's what we are doing, at least...
Isn't this "on you" ? I.e you have to "scope" the join w/ a session ID you create; that's what we are doing, at least...
can you elaborate on what you mean by "scope" the join. Example code would be great. we can definitely do it from different browsers (since its different auth tokens). not sure if we can do it with different tabs from the same browser
Yeah, in your connect
function you can authenticate and also store anything else you want to identify the socket. We generate a session id client side and store this.
def connect(%{"token" => token, "session_id" => session_id}, socket) do
case API.Identity.authenticate(token) do
{:ok, user} ->
socket =
socket
|> assign(:user, user)
|> assign(:session_id, session_id)
|> Absinthe.Phoenix.Socket.put_options(
context: %{
current_user: user
}
)
{:ok, socket}
:error ->
{:error, %{reason: "unauthorized"}}
end
end
yeah, we are storing a session_fingerprint which we get from the authentication library (pow) for each socket connection, so similar to your code above.
However if i had to guess the session_fingerprint is the same for multiple tabs within the same browser (since they are using the same token)
Yes, typically the session is stored in local storage which is shared across tabs..
are you doing anything special with publish when you are publishing data onto the subscription? all our subscriptions are based on the organization, so all users from the same organization, get the same data subscriptions
I checked and the fingerprint is different, so we are scoping the "join" (I think)
Sorry - we are also always publishing to an entire organization for ABSINTHE. We are doing target socket pushes ourselves using presence... So many there's a real bug?
@coladarci you said that each client is getting an identical subscription ID when subscribing? If so, that bit sounds like the bug to me.
No I was making a bad assumption - I got my signals crossed here confusing how we handle absinthe publishing versus our other publishing w/ sockets directly.
OK so each client is getting a different subscription id, but if you publish, both get it? Can you make this more concrete?
I might have the same problem. Here is what I have:
# Web.Schema.Question
object :question_subscriptions do
field :question_change, :question_change do
arg :parent_id, non_null(:id)
config fn %{parent_id: parent_id}, _ -> {:ok, topic: parent_id, context_id: "global"} end
end
end
# Web.Schema
subscription do
import_fields :question_subscriptions
end
# After some save operation
Absinthe.Subscription.publish(
Web.Endpoint,
%{action: action, question: question},
question_change: question.parent_id
)
Now depending on how many clients I have connected, I get the same number of pushes and all clients receive the data.
Here are the logs when I have a Safari, Firefox and Chrome windows connected and all three browser windows receive the payload thrice. If I close one of the windows, the number drops down to 2.
---
[debug] QUERY OK source="questions" db=5.2ms idle=35.0ms
SELECT q0."id", q0."name", q0."body", q0."is_visible", q0."parent_id", q0."speaker_id", q0."inserted_at", q0."updated_at" FROM "questions" AS q0 WHERE (q0."id" = $1) [44]
[debug] QUERY OK db=3.7ms queue=3.1ms idle=42.1ms
UPDATE "questions" SET "name" = $1, "updated_at" = $2 WHERE "id" = $3 ["Name", ~U[2021-04-21 09:24:37Z], 44]
[debug] Absinthe Subscription Publication
Field Topic: 1
Subscription id: "__absinthe__:doc:global:2FD0104E90140DE66FC1D279921023676216746C4760C5C3CF35637D6813451B"
Data: %{data: %{"questionChange" => %{"__typename" => "QuestionChange", "action" => "UPDATED", "record" => %{"__typename" => "Question", "body" => "Body", "id" => "44", "insertedAt" => "2021-04-21T08:12:36Z", "isVisible" => true, "name" => "Name"}}}}
[debug] Absinthe Subscription Publication
Field Topic: 1
Subscription id: "__absinthe__:doc:global:2FD0104E90140DE66FC1D279921023676216746C4760C5C3CF35637D6813451B"
Data: %{data: %{"questionChange" => %{"__typename" => "QuestionChange", "action" => "UPDATED", "record" => %{"__typename" => "Question", "body" => "Body", "id" => "44", "insertedAt" => "2021-04-21T08:12:36Z", "isVisible" => true, "name" => "Name"}}}}
[debug] Absinthe Subscription Publication
Field Topic: 1
Subscription id: "__absinthe__:doc:global:2FD0104E90140DE66FC1D279921023676216746C4760C5C3CF35637D6813451B"
Data: %{data: %{"questionChange" => %{"__typename" => "QuestionChange", "action" => "UPDATED", "record" => %{"__typename" => "Question", "body" => "Body", "id" => "44", "insertedAt" => "2021-04-21T08:12:36Z", "isVisible" => true, "name" => "Name"}}}}
[debug] -- Absinthe Phoenix Reply --
{:ok, %{data: %{"updateQuestion" => %{"__typename" => "Question", "body" => "Body", "id" => "44", "insertedAt" => "2021-04-21T08:12:36Z", "isVisible" => true, "name" => "Name", "speaker" => nil}}}}
----------------------------
We are using subscriptions a fair bit to communicate the state of messages between client and server. At times, the same user will log in via two different browsers.
When this happens, we have the same subscription sent twice to BOTH browsers. They also have the same subscription id.
We have the user object in the absinthe context. We also are using publish_data to publish the subscriptions from the code base (and not via the schema)