Websocket 凤凰频道:每一个请求,我都比以前收到更多的回复
我编写了一个小应用程序(js),可以从服务器获取博客的所有帖子(phoenix framework+PostgreSQL)。该应用程序正在运行,但在第n次调用API时,我收到了n个回复,而不是1个: 也就是说:在第三次通话中,我收到了3个回复,而不是1个。 下面是文件:Websocket 凤凰频道:每一个请求,我都比以前收到更多的回复,websocket,elixir,phoenix-framework,channel,Websocket,Elixir,Phoenix Framework,Channel,我编写了一个小应用程序(js),可以从服务器获取博客的所有帖子(phoenix framework+PostgreSQL)。该应用程序正在运行,但在第n次调用API时,我收到了n个回复,而不是1个: 也就是说:在第三次通话中,我收到了3个回复,而不是1个。 下面是文件:user\u socket.ex: defmodule Proto1.UserSocket do use Phoenix.Socket, Phoenix.LongPoll channel "blog", Proto1.Bl
user\u socket.ex
:
defmodule Proto1.UserSocket do
use Phoenix.Socket, Phoenix.LongPoll
channel "blog", Proto1.BlogChannel
transport :websocket, Phoenix.Transports.WebSocket
transport :longpoll, Phoenix.Transports.LongPoll
def connect(_params, socket) do
{:ok, socket}
end
def id(_socket), do: nil
end
blog\u channel.ex
defmodule Proto1.BlogChannel do
use Proto1.Web, :channel
def join("blog", _message, socket) do
{:ok, socket }
end
def handle_in("getAll", params, socket) do
IO.puts "Proto1.BlogChannel.handle_in \"all\" called"
posts = Repo.all(Proto1.Post)
push socket, "getAll", %{posts: for p <- posts do %{title: p.title, body: p.body} end }
{:noreply, socket}
end
end
插座:
import {Socket} from 'phoenix'
let socket = new Socket('/socket', {params: {token: window.userToken}})
socket.connect()
export default socket
管理频道的一些代码:
import socket from './socket'
class Blog {
// in the future the construcor will have a single parameter with the
// id of the blog, now we hava a single blog
constructor (blogId) {
this._blogId = blogId
this._channel = socket.channel('blog')
this.join()
this.initOn()
}
join () {
this._channel.join()
.receive('ok', resp => { console.log('Joined successfully') })
.receive('error', resp => { console.log('Unable to join') })
}
initOn () {
this._channel.on('all', payload => {
console.log('payload: ', payload)
})
}
getChannel () {
return this._channel
}
}
let BlogFactory = {
blogs: new Map(),
getBlog: function (blogId = 'default') {
if (this.blogs[blogId] === undefined) {
this.blogs[blogId] = new Blog(blogId)
}
return this.blogs[blogId]
}
}
export default BlogFactory
数据获取:
[...]
methods: {
fetchData () {
this.error = this.posts = null
this.loading = true
var blog = BlogFactory.getBlog()
var c = blog.getChannel()
c.on('getAll', payload => {
console.log('client getAll reply, ', payload)
this.loading = false
this.posts = payload.posts
})
console.log('client getAll call')
c.push('getAll')
}
}
[...]
在回答@Nicd之后更改了客户端程序(以下代码有效!):
<script>
// import BlogFactory from '../blog'
import socket from '../socket'
export default {
name: 'blog',
data () {
return {
loading: false,
posts: null,
error: null
}
},
created () {
this.channel = socket.channel('blog')
this.channel.join()
.receive('ok', resp => { console.log('Joined successfully') })
.receive('error', resp => { console.log('Unable to join') })
this.channel.on('getAll', payload => {
console.log('client getAll reply, ', payload)
this.loading = false
this.posts = payload.posts
})
this.fetchData()
},
methods: {
fetchData () {
this.error = this.posts = null
this.loading = true
console.log('client getAll call')
this.channel.push('getAll')
}
}
}
</script>
//从“../blog”导入BlogFactory
从“../socket”导入套接字
导出默认值{
名称:'博客',
数据(){
返回{
加载:false,
posts:null,
错误:null
}
},
创建(){
this.channel=socket.channel('blog'))
this.channel.join()
.receive('ok',resp=>{console.log('Joined successfully')})
.receive('error',resp=>{console.log('Unable to join')})
this.channel.on('getAll',payload=>{
log('client getAll reply',有效负载)
此参数为0。加载=错误
this.posts=payload.posts
})
this.fetchData()
},
方法:{
获取数据(){
this.error=this.posts=null
这是真的
console.log('client getAll call')
this.channel.push('getAll'))
}
}
}
似乎每次调用fetchData()
,您都在使用c.on('getAll',…)
调用添加一个新的侦听器。因此,对于每一条收到的消息,您都会运行越来越多的侦听器,这就是为什么看起来您收到了很多消息
您可以使用浏览器的开发工具检查这一点–至少基于Chrome的浏览器允许您检查WebSocket流量,以查看是否只有一条收到的消息
[...]
methods: {
fetchData () {
this.error = this.posts = null
this.loading = true
var blog = BlogFactory.getBlog()
var c = blog.getChannel()
c.on('getAll', payload => {
console.log('client getAll reply, ', payload)
this.loading = false
this.posts = payload.posts
})
console.log('client getAll call')
c.push('getAll')
}
}
[...]
<script>
// import BlogFactory from '../blog'
import socket from '../socket'
export default {
name: 'blog',
data () {
return {
loading: false,
posts: null,
error: null
}
},
created () {
this.channel = socket.channel('blog')
this.channel.join()
.receive('ok', resp => { console.log('Joined successfully') })
.receive('error', resp => { console.log('Unable to join') })
this.channel.on('getAll', payload => {
console.log('client getAll reply, ', payload)
this.loading = false
this.posts = payload.posts
})
this.fetchData()
},
methods: {
fetchData () {
this.error = this.posts = null
this.loading = true
console.log('client getAll call')
this.channel.push('getAll')
}
}
}
</script>