3

我正在使用 phoenix 框架来创建不同类型的聊天应用程序。就我而言,我们有聊天室,但不能像普通的聊天室一样运作。

每个用户都有自己的房间,他可以使用不同的设备(移动设备、个人电脑、其他一些来源)加入自己的房间。

用户 A 有自己的房间,用户 B 有自己的房间,这两个成员不像现实世界中的正常场景那样连接到一个房间。

现在我的用户 A 想向用户 B 发送消息

消息数据,例如:

from : A  
to :B  
message : test message   

这是app.js我用来连接到用户特定房间的片段:

let room = socket.channel("room:"+  user, {})
room.on("presence_state", state => {
  presences = Presence.syncState(presences, status)
  console.log(presences)
  render(presences)
})

这是加入房间功能的后端片段
/web/channel/RoomChannel.ex

  def join("room:" <> _user, _, socket) do
    send self(), :after_join
    {:ok, socket}
  end

但现在我被困在中间,因为我找不到在用户之间发送消息的方法。例如:无法确定使用此特定场景将用户 A 的消息传递给用户 B 的方式

这是此聊天应用程序的基本架构师:

在此处输入图像描述

这是 Roomchannel 文件中的其余代码

def handle_info(:after_join, socket) do
    Presence.track(socket, socket.assigns.user, %{
      online_at: :os.system_time(:millisecond)

    })
    push socket, "presence_state", Presence.list(socket)
    {:noreply, socket}
  end

  def handle_in("message:new", message, socket) do
    broadcast! socket, "message:new", %{
      user: socket.assigns.user,
      body: message,
      timestamp: :os.system_time(:millisecond)
    }
    milisecondstime = :os.system_time(:millisecond)
    [room, user] = String.split(Map.get(socket, :topic), ":")
    data = Poison.encode!(%{"created_at" => :os.system_time(:millisecond), "updated_at" => :os.system_time(:millisecond), "uuid" => UUID.uuid1(), "date" => :os.system_time(:millisecond), "from" => user, "to" => user, "message" => message})
    Redix.command(:redix, ["SET", UUID.uuid1(), data]) 
    {:noreply, socket}
  end

谁能告诉我一些可以在用户聊天室之间传递消息的方法?

redis用来存储数据, 是我正在关注的基本聊天应用程序,感谢该开发人员。

4

1 回答 1

2

查看您可以使用该功能Phoenix.Endpoint.broadcast 向给定主题发送消息broadcast/3


另一种方法是在用户加入频道join功能时为每个用户订阅一个唯一的私人主题

def join("room:" <> _user, _, socket) do
    send self(), :after_join
    MyApp.Endpoint.subscribe("private-room:" <> user) # subscribe the connecting client to their private room
    {:ok, socket}
end

然后handle_in("message:new",message, socket)从消息有效负载中提取接收者用户 ID 并调用

Endpoint.broadcast

def handle_in("message:new", message, socket) do

    MyApp.Endpoint.broadcast!("private-room:" <> to_user , "message:new",%{
        user: socket.assigns.user,
        body: message,
        timestamp: :os.system_time(:millisecond)
   }) #sends the message to all connected clients for the to_user

    {:noreply, socket}
end
于 2017-07-27T01:41:59.043 回答