在 Rails 和 React 中实现 Pusher Chat
Implementing Pusher Chat in Rails and React
我正在使用 this repo 在 Rails 和 React 项目中创建两个用户之间的聊天系统。我已经能够将用户输入记录到控制台中,并且根据回购协议创建了 messages_controller 和 message_threads_controller。
但是,我无法将消息持久保存到 Rails 数据库,然后在将其发送到 Pusher 之前使用 Pusher 对用户进行身份验证。主要是因为 from_uid、to_uid 和 thread_uid 在消息发送到 Rails 时不存在。像这样向 rails 发送消息:
sendMessage = (event) => {
event.preventDefault();
const {message} = this.state;
axios.post('/api/v1/messages', {message: message})
.then((response) => {
console.log(response);
})
console.log('send Message')
this.setState({'message': message});
console.log(this.state.message);
}
在我的 routes.rb 文件中我有这个
resources :messages
get 'threads/:id', to: 'message_threads#index'
post '/pusher/auth', to: 'pusher#auth'
我缺少一些必需的参数,这是我收到的错误。
Pusher::Error - Bad request: Missing required parameter:
按照this tutorial的流程,消息需要先被rails数据库持久化,然后再发送给Pusher。
我现在的问题是如何生成在 the app here 的 React 端使用的额外参数(from_uid、thread_uid、to_uid),以启用要创建的消息?
此外,如何使用 Pusher 对用户进行身份验证?
根据这个 Stack Overflow link 他们从 Rails 得到这样的 CSRF 值 - csrf = $('meta[name=csrf-token]').attr('content')
。但我无法在 React 中实现相同的功能。
来自 git 存储库作者的回答。
我在此处创建的示例非常简单,但下面是一些要点,我希望它们能解释您如何扩展它。
- 向 Rails 应用添加用户模型和线程模型
- 创建User时,为用户生成一个public UID(可以使用Ruby的built-in
SecureRandom.uuid
生成id)并保存那给数据库。这将成为您将在 javascript 中公开的该用户的 ID,以允许用户之间进行通信。所有用户都会有一个 UID。
- 创建线程时,会生成一个线程 UID,这将成为正在进行的对话的唯一 ID
- 添加 Users_Threads
has_and_belongs_to_many
关系,以便您最终可以跟踪订阅了哪些线程的用户
- 当 React 应用程序加载时,使用 Ajax 请求获取当前用户的好友列表(returns 用户详细信息列表 + 他们的 uid)和获取当前用户所有线程的请求用户
- 例如,一个名为 Fred 的用户单击了一个名为 Bob 的用户,并想向 Bob 发送一条消息,但他们目前没有线程。 Fred 键入消息,单击提交,然后您发送一个 Ajax 请求,其中包含消息文本,from_uid (Fred) 和 to_uid (Bob),其中 thread_uid 为空(因为那里没有现有的会议,也没有现有的线程)。
- 您的 Rails 应用随后在控制器上接收到该请求,并发现 Fred 正在尝试向 Bob 发送消息并且线程 ID 为空,因此控制器创建了一个新线程(具有自己的 UID)然后向 users_threads 添加两个条目,一个用于新的 thread_uid 和 bob 的 uid,另一个用于新的 thread_uid 和 Fred 的 uid。之后,您将使用 thread_uid 和参与者详细信息创建一条消息。
您可能还希望用户看到他们是新话题的一部分而无需重新加载页面,所以我认为您希望订阅 Pusher 频道只是为了通知用户有新话题.所以我会说在 UserThreads 模型中创建一个新线程后你可以发送类似 Pusher.trigger('threads_channel', user_secret_uid, { thread: new_thread_uid })
的内容。您还需要在 React 应用程序中确保每个用户都为他们的 user_secret_uid 订阅了 threads_channel。为了安全起见,我会确保这与消息传递的 uid 不同,否则人们可以订阅不同用户线程的列表。
我正在使用 this repo 在 Rails 和 React 项目中创建两个用户之间的聊天系统。我已经能够将用户输入记录到控制台中,并且根据回购协议创建了 messages_controller 和 message_threads_controller。
但是,我无法将消息持久保存到 Rails 数据库,然后在将其发送到 Pusher 之前使用 Pusher 对用户进行身份验证。主要是因为 from_uid、to_uid 和 thread_uid 在消息发送到 Rails 时不存在。像这样向 rails 发送消息:
sendMessage = (event) => {
event.preventDefault();
const {message} = this.state;
axios.post('/api/v1/messages', {message: message})
.then((response) => {
console.log(response);
})
console.log('send Message')
this.setState({'message': message});
console.log(this.state.message);
}
在我的 routes.rb 文件中我有这个
resources :messages
get 'threads/:id', to: 'message_threads#index'
post '/pusher/auth', to: 'pusher#auth'
我缺少一些必需的参数,这是我收到的错误。
Pusher::Error - Bad request: Missing required parameter:
按照this tutorial的流程,消息需要先被rails数据库持久化,然后再发送给Pusher。
我现在的问题是如何生成在 the app here 的 React 端使用的额外参数(from_uid、thread_uid、to_uid),以启用要创建的消息?
此外,如何使用 Pusher 对用户进行身份验证?
根据这个 Stack Overflow link 他们从 Rails 得到这样的 CSRF 值 - csrf = $('meta[name=csrf-token]').attr('content')
。但我无法在 React 中实现相同的功能。
来自 git 存储库作者的回答。
我在此处创建的示例非常简单,但下面是一些要点,我希望它们能解释您如何扩展它。
- 向 Rails 应用添加用户模型和线程模型
- 创建User时,为用户生成一个public UID(可以使用Ruby的built-in
SecureRandom.uuid
生成id)并保存那给数据库。这将成为您将在 javascript 中公开的该用户的 ID,以允许用户之间进行通信。所有用户都会有一个 UID。 - 创建线程时,会生成一个线程 UID,这将成为正在进行的对话的唯一 ID
- 添加 Users_Threads
has_and_belongs_to_many
关系,以便您最终可以跟踪订阅了哪些线程的用户 - 当 React 应用程序加载时,使用 Ajax 请求获取当前用户的好友列表(returns 用户详细信息列表 + 他们的 uid)和获取当前用户所有线程的请求用户
- 例如,一个名为 Fred 的用户单击了一个名为 Bob 的用户,并想向 Bob 发送一条消息,但他们目前没有线程。 Fred 键入消息,单击提交,然后您发送一个 Ajax 请求,其中包含消息文本,from_uid (Fred) 和 to_uid (Bob),其中 thread_uid 为空(因为那里没有现有的会议,也没有现有的线程)。
- 您的 Rails 应用随后在控制器上接收到该请求,并发现 Fred 正在尝试向 Bob 发送消息并且线程 ID 为空,因此控制器创建了一个新线程(具有自己的 UID)然后向 users_threads 添加两个条目,一个用于新的 thread_uid 和 bob 的 uid,另一个用于新的 thread_uid 和 Fred 的 uid。之后,您将使用 thread_uid 和参与者详细信息创建一条消息。
您可能还希望用户看到他们是新话题的一部分而无需重新加载页面,所以我认为您希望订阅 Pusher 频道只是为了通知用户有新话题.所以我会说在 UserThreads 模型中创建一个新线程后你可以发送类似 Pusher.trigger('threads_channel', user_secret_uid, { thread: new_thread_uid })
的内容。您还需要在 React 应用程序中确保每个用户都为他们的 user_secret_uid 订阅了 threads_channel。为了安全起见,我会确保这与消息传递的 uid 不同,否则人们可以订阅不同用户线程的列表。