Redux 传奇未在实时套接字上调度操作

Redux saga not dispatching action on live sockets

我正在尝试使用 redux-saga 在实时套接字上出现响应时分派一个动作。 我已经能够到达应该放置(调度)操作的代码行,但只有在这种实时套接字情况下,实时操作才不会调度。

这是我的代码:

export function* watchEditorAcceptInvitatioRequest(action) {
    yield takeEvery(START_EDITOR_ACCEPT_INVITATION_SOCKET, edditorAcceptInvitationSocket)
}

export function* edditorAcceptInvitationSocket(action) {
    const {token, user_id} = action.payload
    const subscription = SocketIo.subscribe(token, '/broadcasting/authTest')

    yield put(listenEditorAcceptInvitationSocket())
    let result = yield call(SocketIo.listen, subscription, `new-test-channel.${user_id}`,
        '.new-test-test', (response) => edditorAcceptInvitationReceived({
            func: receiveEditorAcceptInvitationSocket,
            response: response
        }))

}

export function* edditorAcceptInvitationReceived(action) {
    while(true) {

        console.log(action.response) // I am seeing this in response but the action put in blow line
        yield put(action.func(action.response))
    }
}

下面是socket订阅和监听代码:

import Echo from 'laravel-echo'
import Socketio from 'socket.io-client'

const BASE_URL = 'https://www.my domain.com'
const PORT = 1111

const subscribe = (token, authEndpoint) => new Echo({
    broadcaster: 'socket.io',
    host: `${BASE_URL}:${PORT}`,
    client: Socketio,
    authEndpoint: authEndpoint,
    auth: {
        headers: {
            Authorization: 'Bearer ' + token,
            Accept: 'application/json',
        },
    },
})

const listen = (echo, channel, event, callback) => {
    echo.private(channel).listen(event, e => {
        const generator = callback(e)
        generator.next()
    })
}

export default {
    subscribe,
    listen
}

这里缺少什么,我们将不胜感激。

我用 eventChannel

解决了这个问题

上面例子的工作代码是:

export function* watchEditorAcceptInvitatioRequest(action) {
    yield takeEvery(START_EDITOR_ACCEPT_INVITATION_SOCKET, edditorAcceptInvitationSocket)
}

export function* edditorAcceptInvitationSocket(action) {
    const {token, user_id} = action.payload
    const subscription = SocketIo.subscribe(token, '/broadcasting/authTest')
    yield put(listenEditorAcceptInvitationSocket())
    let channel = yield call(SocketIo.listen, subscription, `new-test-channel.${user_id}`,
        '.new-test-test', receiveEditorAcceptInvitationSocket)
    while (true) {
        const action = yield take(channel)
        yield put(action)
    }
}

下面是更新的套接字订阅和监听代码:

从“../store/configureStore”导入商店 从 'laravel-echo' 导入 Echo 从 'socket.io-client' 导入 Socketio 从 'redux-saga'

导入 {eventChannel}
const BASE_URL = 'https://www.my domain.com'
const PORT = 1111

const subscribe = (token, authEndpoint) => new Echo({
    broadcaster: 'socket.io',
    host: `${BASE_URL}:${PORT}`,
    client: Socketio,
    authEndpoint: authEndpoint,
    auth: {
        headers: {
            Authorization: 'Bearer ' + token,
            Accept: 'application/json',
        },
    },
})

const listen = (echo, channel, event, callback) => {
    return eventChannel( emitter => {
        echo.private(channel).listen(event, e => {
            emitter(store.dispatch(callback(e)))
        })
        return () => {
            console.log('returning channel')
        }
    })}

export default {
    subscribe,
    listen
}