모든 게시물을 서버 (phoenix 프레임 워크 + PostgreSQL)에서 가져 오는 작은 앱 (js)을 프로그래밍했습니다. 응용 프로그램은 작동하고 있지만, API의 N 번째 호출에서, 나는 얻을 대신 의 응답N :피닉스 채널 : 모든 요청마다 이전보다 더 많은 답장을받습니다.
입니다Joined successfully app.js:18747:10
client getAll call app.js:18698:8
client getAll reply, Object { posts: Array[3] } app.js:18694:10
client getAll call app.js:18698:8
client getAll reply, Object { posts: Array[3] } app.js:18694:10
client getAll reply, Object { posts: Array[3] } app.js:18694:10
client getAll call app.js:18698:8
client getAll reply, Object { posts: Array[3] } app.js:18694:10
client getAll reply, Object { posts: Array[3] } app.js:18694:10
client getAll reply, Object { posts: Array[3] }
: 3 호에 내가 3가 대신 대답 얻을 1. 다음
파일 : user_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_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
그리고 클라이언트에서
(vue.js 2) : 끝점 :defmodule Proto1.Endpoint do
use Phoenix.Endpoint, otp_app: :proto1
socket "/socket", Proto1.UserSocket
소켓 :
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
: import {Socket} from 'phoenix'
let socket = new Socket('/socket', {params: {token: window.userToken}})
socket.connect()
export default socket
채널을 관리 할 수있는 몇 가지 코드
데이터 가져 오기 :
[...]
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>