Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Websocket 凤凰频道:每一个请求,我都比以前收到更多的回复_Websocket_Elixir_Phoenix Framework_Channel - Fatal编程技术网

Websocket 凤凰频道:每一个请求,我都比以前收到更多的回复

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

我编写了一个小应用程序(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.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>